From a574ac68baf3dd59d80a81aa98b0ed036b34018e Mon Sep 17 00:00:00 2001 From: Techatrix <19954306+Techatrix@users.noreply.github.com> Date: Tue, 3 Jan 2023 15:21:58 +0000 Subject: [PATCH 01/24] use more explicit error sets (#880) --- src/DocumentStore.zig | 6 +- src/Server.zig | 133 +++++++++++++++++++++++------------------- src/analysis.zig | 4 +- src/configuration.zig | 2 +- 4 files changed, 78 insertions(+), 67 deletions(-) diff --git a/src/DocumentStore.zig b/src/DocumentStore.zig index d78d809..318bd1a 100644 --- a/src/DocumentStore.zig +++ b/src/DocumentStore.zig @@ -921,7 +921,7 @@ pub fn uriFromImportStr(self: *const DocumentStore, allocator: std.mem.Allocator } } -fn tagStoreCompletionItems(self: DocumentStore, arena: std.mem.Allocator, handle: Handle, comptime name: []const u8) ![]types.CompletionItem { +fn tagStoreCompletionItems(self: DocumentStore, arena: std.mem.Allocator, handle: Handle, comptime name: []const u8) error{OutOfMemory}![]types.CompletionItem { const tracy_zone = tracy.trace(@src()); defer tracy_zone.end(); @@ -944,11 +944,11 @@ fn tagStoreCompletionItems(self: DocumentStore, arena: std.mem.Allocator, handle return result_set.entries.items(.key); } -pub fn errorCompletionItems(self: DocumentStore, arena: std.mem.Allocator, handle: Handle) ![]types.CompletionItem { +pub fn errorCompletionItems(self: DocumentStore, arena: std.mem.Allocator, handle: Handle) error{OutOfMemory}![]types.CompletionItem { return try self.tagStoreCompletionItems(arena, handle, "error_completions"); } -pub fn enumCompletionItems(self: DocumentStore, arena: std.mem.Allocator, handle: Handle) ![]types.CompletionItem { +pub fn enumCompletionItems(self: DocumentStore, arena: std.mem.Allocator, handle: Handle) error{OutOfMemory}![]types.CompletionItem { return try self.tagStoreCompletionItems(arena, handle, "enum_completions"); } diff --git a/src/Server.zig b/src/Server.zig index 5f750c4..265f823 100644 --- a/src/Server.zig +++ b/src/Server.zig @@ -66,8 +66,7 @@ const ClientCapabilities = packed struct { supports_configuration: bool = false, }; -/// TODO remove anyerror -pub const Error = anyerror || std.mem.Allocator.Error || error{ +pub const Error = std.mem.Allocator.Error || error{ ParseError, InvalidRequest, MethodNotFound, @@ -138,7 +137,7 @@ fn sendInternal( maybe_err: ?types.ResponseError, extra_name: []const u8, extra: anytype, -) !void { +) error{OutOfMemory}!void { var buffer = std.ArrayListUnmanaged(u8){}; var writer = buffer.writer(server.allocator); try writer.writeAll( @@ -191,7 +190,7 @@ fn showMessage( }); } -fn generateDiagnostics(server: *Server, handle: DocumentStore.Handle) !types.PublishDiagnosticsParams { +fn generateDiagnostics(server: *Server, handle: DocumentStore.Handle) error{OutOfMemory}!types.PublishDiagnosticsParams { const tracy_zone = tracy.trace(@src()); defer tracy_zone.end(); @@ -205,7 +204,7 @@ fn generateDiagnostics(server: *Server, handle: DocumentStore.Handle) !types.Pub for (tree.errors) |err| { var mem_buffer: [256]u8 = undefined; var fbs = std.io.fixedBufferStream(&mem_buffer); - try tree.renderError(err, fbs.writer()); + tree.renderError(err, fbs.writer()) catch if (std.debug.runtime_safety) unreachable else continue; // if an error occurs here increase buffer size try diagnostics.append(allocator, .{ .range = offsets.tokenToRange(tree, err.token, server.offset_encoding), @@ -218,7 +217,9 @@ fn generateDiagnostics(server: *Server, handle: DocumentStore.Handle) !types.Pub } if (server.config.enable_ast_check_diagnostics and tree.errors.len == 0) { - try getAstCheckDiagnostics(server, handle, &diagnostics); + getAstCheckDiagnostics(server, handle, &diagnostics) catch |err| { + log.err("failed to run ast-check: {}", .{err}); + }; } if (server.config.warn_style) { @@ -485,12 +486,14 @@ fn getAutofixMode(server: *Server) enum { } /// caller owns returned memory. -fn autofix(server: *Server, allocator: std.mem.Allocator, handle: *const DocumentStore.Handle) !std.ArrayListUnmanaged(types.TextEdit) { +fn autofix(server: *Server, allocator: std.mem.Allocator, handle: *const DocumentStore.Handle) error{OutOfMemory}!std.ArrayListUnmanaged(types.TextEdit) { if (!server.config.enable_ast_check_diagnostics) return .{}; if (handle.tree.errors.len != 0) return .{}; var diagnostics = std.ArrayListUnmanaged(types.Diagnostic){}; - try getAstCheckDiagnostics(server, handle.*, &diagnostics); + getAstCheckDiagnostics(server, handle.*, &diagnostics) catch |err| { + log.err("failed to run ast-check: {}", .{err}); + }; var builder = code_actions.Builder{ .arena = server.arena, @@ -1086,7 +1089,7 @@ fn getSymbolFieldAccess( handle: *const DocumentStore.Handle, source_index: usize, loc: offsets.Loc, -) !?analysis.DeclWithHandle { +) error{OutOfMemory}!?analysis.DeclWithHandle { const tracy_zone = tracy.trace(@src()); defer tracy_zone.end(); @@ -1167,7 +1170,7 @@ const DeclToCompletionContext = struct { parent_is_type_val: ?bool = null, }; -fn declToCompletion(context: DeclToCompletionContext, decl_handle: analysis.DeclWithHandle) !void { +fn declToCompletion(context: DeclToCompletionContext, decl_handle: analysis.DeclWithHandle) error{OutOfMemory}!void { const tracy_zone = tracy.trace(@src()); defer tracy_zone.end(); @@ -1227,7 +1230,7 @@ fn completeLabel( server: *Server, pos_index: usize, handle: *const DocumentStore.Handle, -) ![]types.CompletionItem { +) error{OutOfMemory}![]types.CompletionItem { const tracy_zone = tracy.trace(@src()); defer tracy_zone.end(); @@ -1267,7 +1270,7 @@ fn populateSnippedCompletions( } } -fn completeGlobal(server: *Server, pos_index: usize, handle: *const DocumentStore.Handle) ![]types.CompletionItem { +fn completeGlobal(server: *Server, pos_index: usize, handle: *const DocumentStore.Handle) error{OutOfMemory}![]types.CompletionItem { const tracy_zone = tracy.trace(@src()); defer tracy_zone.end(); @@ -1290,7 +1293,7 @@ fn completeGlobal(server: *Server, pos_index: usize, handle: *const DocumentStor return completions.toOwnedSlice(server.arena.allocator()); } -fn completeFieldAccess(server: *Server, handle: *const DocumentStore.Handle, source_index: usize, loc: offsets.Loc) !?[]types.CompletionItem { +fn completeFieldAccess(server: *Server, handle: *const DocumentStore.Handle, source_index: usize, loc: offsets.Loc) error{OutOfMemory}!?[]types.CompletionItem { const tracy_zone = tracy.trace(@src()); defer tracy_zone.end(); @@ -1312,7 +1315,7 @@ fn completeFieldAccess(server: *Server, handle: *const DocumentStore.Handle, sou return try completions.toOwnedSlice(allocator); } -fn formatDetailledLabel(item: *types.CompletionItem, alloc: std.mem.Allocator) !void { +fn formatDetailledLabel(item: *types.CompletionItem, alloc: std.mem.Allocator) error{OutOfMemory}!void { // NOTE: this is not ideal, we should build a detailled label like we do for label/detail // because this implementation is very loose, nothing is formated properly so we need to clean // things a little bit, wich is quite messy @@ -1478,7 +1481,7 @@ fn formatDetailledLabel(item: *types.CompletionItem, alloc: std.mem.Allocator) ! // logger.info("labelDetails: {s} :: {s}", .{item.labelDetails.?.detail, item.labelDetails.?.description}); } -fn completeError(server: *Server, handle: *const DocumentStore.Handle) ![]types.CompletionItem { +fn completeError(server: *Server, handle: *const DocumentStore.Handle) error{OutOfMemory}![]types.CompletionItem { const tracy_zone = tracy.trace(@src()); defer tracy_zone.end(); @@ -1513,7 +1516,7 @@ fn kindToSortScore(kind: types.CompletionItemKind) ?[]const u8 { }; } -fn completeDot(server: *Server, handle: *const DocumentStore.Handle) ![]types.CompletionItem { +fn completeDot(server: *Server, handle: *const DocumentStore.Handle) error{OutOfMemory}![]types.CompletionItem { const tracy_zone = tracy.trace(@src()); defer tracy_zone.end(); @@ -1578,7 +1581,7 @@ fn completeFileSystemStringLiteral(allocator: std.mem.Allocator, store: *const D return completions.toOwnedSlice(allocator); } -fn initializeHandler(server: *Server, request: types.InitializeParams) !types.InitializeResult { +fn initializeHandler(server: *Server, request: types.InitializeParams) Error!types.InitializeResult { const tracy_zone = tracy.trace(@src()); defer tracy_zone.end(); @@ -1794,7 +1797,7 @@ fn initializeHandler(server: *Server, request: types.InitializeParams) !types.In }; } -fn initializedHandler(server: *Server, notification: types.InitializedParams) !void { +fn initializedHandler(server: *Server, notification: types.InitializedParams) Error!void { _ = notification; if (server.status != .initializing) { @@ -1807,7 +1810,7 @@ fn initializedHandler(server: *Server, notification: types.InitializedParams) !v try server.requestConfiguration(); } -fn shutdownHandler(server: *Server, _: void) !?void { +fn shutdownHandler(server: *Server, _: void) Error!?void { if (server.status != .initialized) return error.InvalidRequest; // received a shutdown request but the server is not initialized! // Technically we should deinitialize first and send possible errors to the client @@ -1826,13 +1829,13 @@ fn exitHandler(server: *Server, _: void) noreturn { std.os.exit(error_code); } -fn cancelRequestHandler(server: *Server, request: types.CancelParams) !void { +fn cancelRequestHandler(server: *Server, request: types.CancelParams) Error!void { _ = server; _ = request; // TODO implement $/cancelRequest } -fn registerCapability(server: *Server, method: []const u8) !void { +fn registerCapability(server: *Server, method: []const u8) Error!void { const allocator = server.arena.allocator(); const id = try std.fmt.allocPrint(allocator, "register-{s}", .{method}); @@ -1851,7 +1854,7 @@ fn registerCapability(server: *Server, method: []const u8) !void { ); } -fn requestConfiguration(server: *Server) !void { +fn requestConfiguration(server: *Server) Error!void { if (server.recording_enabled) { log.info("workspace/configuration are disabled during a recording session!", .{}); return; @@ -1938,7 +1941,7 @@ fn handleConfiguration(server: *Server, json: std.json.Value) error{OutOfMemory} }; } -fn openDocumentHandler(server: *Server, notification: types.DidOpenTextDocumentParams) !void { +fn openDocumentHandler(server: *Server, notification: types.DidOpenTextDocumentParams) Error!void { const tracy_zone = tracy.trace(@src()); defer tracy_zone.end(); @@ -1950,7 +1953,7 @@ fn openDocumentHandler(server: *Server, notification: types.DidOpenTextDocumentP } } -fn changeDocumentHandler(server: *Server, notification: types.DidChangeTextDocumentParams) !void { +fn changeDocumentHandler(server: *Server, notification: types.DidChangeTextDocumentParams) Error!void { const tracy_zone = tracy.trace(@src()); defer tracy_zone.end(); @@ -1966,7 +1969,7 @@ fn changeDocumentHandler(server: *Server, notification: types.DidChangeTextDocum } } -fn saveDocumentHandler(server: *Server, notification: types.DidSaveTextDocumentParams) !void { +fn saveDocumentHandler(server: *Server, notification: types.DidSaveTextDocumentParams) Error!void { const tracy_zone = tracy.trace(@src()); defer tracy_zone.end(); @@ -2000,7 +2003,7 @@ fn closeDocumentHandler(server: *Server, notification: types.DidCloseTextDocumen server.document_store.closeDocument(notification.textDocument.uri); } -fn willSaveWaitUntilHandler(server: *Server, request: types.WillSaveTextDocumentParams) !?[]types.TextEdit { +fn willSaveWaitUntilHandler(server: *Server, request: types.WillSaveTextDocumentParams) Error!?[]types.TextEdit { const tracy_zone = tracy.trace(@src()); defer tracy_zone.end(); @@ -2015,7 +2018,7 @@ fn willSaveWaitUntilHandler(server: *Server, request: types.WillSaveTextDocument return try text_edits.toOwnedSlice(allocator); } -fn semanticTokensFullHandler(server: *Server, request: types.SemanticTokensParams) !?types.SemanticTokens { +fn semanticTokensFullHandler(server: *Server, request: types.SemanticTokensParams) Error!?types.SemanticTokens { const tracy_zone = tracy.trace(@src()); defer tracy_zone.end(); @@ -2028,7 +2031,7 @@ fn semanticTokensFullHandler(server: *Server, request: types.SemanticTokensParam return .{ .data = token_array }; } -fn completionHandler(server: *Server, request: types.CompletionParams) !?types.CompletionList { +fn completionHandler(server: *Server, request: types.CompletionParams) Error!?types.CompletionList { const tracy_zone = tracy.trace(@src()); defer tracy_zone.end(); @@ -2056,7 +2059,10 @@ fn completionHandler(server: *Server, request: types.CompletionParams) !?types.C const completing = offsets.locToSlice(handle.tree.source, loc); const is_import = pos_context == .import_string_literal; - break :blk try completeFileSystemStringLiteral(server.arena.allocator(), &server.document_store, handle, completing, is_import); + break :blk completeFileSystemStringLiteral(server.arena.allocator(), &server.document_store, handle, completing, is_import) catch |err| { + log.err("failed to get file system completions: {}", .{err}); + return null; + }; }, else => null, }; @@ -2082,7 +2088,7 @@ fn completionHandler(server: *Server, request: types.CompletionParams) !?types.C return .{ .isIncomplete = false, .items = completions }; } -fn signatureHelpHandler(server: *Server, request: types.SignatureHelpParams) !?types.SignatureHelp { +fn signatureHelpHandler(server: *Server, request: types.SignatureHelpParams) Error!?types.SignatureHelp { const tracy_zone = tracy.trace(@src()); defer tracy_zone.end(); @@ -2111,7 +2117,7 @@ fn signatureHelpHandler(server: *Server, request: types.SignatureHelpParams) !?t }; } -fn gotoHandler(server: *Server, request: types.TextDocumentPositionParams, resolve_alias: bool) !?types.Location { +fn gotoHandler(server: *Server, request: types.TextDocumentPositionParams, resolve_alias: bool) Error!?types.Location { const tracy_zone = tracy.trace(@src()); defer tracy_zone.end(); @@ -2134,7 +2140,7 @@ fn gotoHandler(server: *Server, request: types.TextDocumentPositionParams, resol fn gotoDefinitionHandler( server: *Server, request: types.TextDocumentPositionParams, -) !?types.Location { +) Error!?types.Location { const tracy_zone = tracy.trace(@src()); defer tracy_zone.end(); @@ -2144,14 +2150,14 @@ fn gotoDefinitionHandler( fn gotoDeclarationHandler( server: *Server, request: types.TextDocumentPositionParams, -) !?types.Location { +) Error!?types.Location { const tracy_zone = tracy.trace(@src()); defer tracy_zone.end(); return try server.gotoHandler(request, false); } -fn hoverHandler(server: *Server, request: types.HoverParams) !?types.Hover { +fn hoverHandler(server: *Server, request: types.HoverParams) Error!?types.Hover { const tracy_zone = tracy.trace(@src()); defer tracy_zone.end(); @@ -2179,7 +2185,7 @@ fn hoverHandler(server: *Server, request: types.HoverParams) !?types.Hover { return response; } -fn documentSymbolsHandler(server: *Server, request: types.DocumentSymbolParams) !?[]types.DocumentSymbol { +fn documentSymbolsHandler(server: *Server, request: types.DocumentSymbolParams) Error!?[]types.DocumentSymbol { const tracy_zone = tracy.trace(@src()); defer tracy_zone.end(); @@ -2188,7 +2194,7 @@ fn documentSymbolsHandler(server: *Server, request: types.DocumentSymbolParams) return try analysis.getDocumentSymbols(server.arena.allocator(), handle.tree, server.offset_encoding); } -fn formattingHandler(server: *Server, request: types.DocumentFormattingParams) !?[]types.TextEdit { +fn formattingHandler(server: *Server, request: types.DocumentFormattingParams) Error!?[]types.TextEdit { const tracy_zone = tracy.trace(@src()); defer tracy_zone.end(); @@ -2224,7 +2230,7 @@ fn formattingHandler(server: *Server, request: types.DocumentFormattingParams) ! return text_edits.items; } -fn didChangeConfigurationHandler(server: *Server, request: configuration.DidChangeConfigurationParams) !void { +fn didChangeConfigurationHandler(server: *Server, request: configuration.DidChangeConfigurationParams) Error!void { const tracy_zone = tracy.trace(@src()); defer tracy_zone.end(); @@ -2244,13 +2250,15 @@ fn didChangeConfigurationHandler(server: *Server, request: configuration.DidChan } } - try configuration.configChanged(server.config, server.allocator, null); + configuration.configChanged(server.config, server.allocator, null) catch |err| { + log.err("failed to update config: {}", .{err}); + }; } else if (server.client_capabilities.supports_configuration) { try server.requestConfiguration(); } } -fn renameHandler(server: *Server, request: types.RenameParams) !?types.WorkspaceEdit { +fn renameHandler(server: *Server, request: types.RenameParams) Error!?types.WorkspaceEdit { const tracy_zone = tracy.trace(@src()); defer tracy_zone.end(); @@ -2258,7 +2266,7 @@ fn renameHandler(server: *Server, request: types.RenameParams) !?types.Workspace return if (response) |rep| rep.rename else null; } -fn referencesHandler(server: *Server, request: types.ReferenceParams) !?[]types.Location { +fn referencesHandler(server: *Server, request: types.ReferenceParams) Error!?[]types.Location { const tracy_zone = tracy.trace(@src()); defer tracy_zone.end(); @@ -2266,7 +2274,7 @@ fn referencesHandler(server: *Server, request: types.ReferenceParams) !?[]types. return if (response) |rep| rep.references else null; } -fn documentHighlightHandler(server: *Server, request: types.DocumentHighlightParams) !?[]types.DocumentHighlight { +fn documentHighlightHandler(server: *Server, request: types.DocumentHighlightParams) Error!?[]types.DocumentHighlight { const tracy_zone = tracy.trace(@src()); defer tracy_zone.end(); @@ -2302,7 +2310,7 @@ const GeneralReferencesResponse = union { highlight: []types.DocumentHighlight, }; -fn generalReferencesHandler(server: *Server, request: GeneralReferencesRequest) !?GeneralReferencesResponse { +fn generalReferencesHandler(server: *Server, request: GeneralReferencesRequest) Error!?GeneralReferencesResponse { const tracy_zone = tracy.trace(@src()); defer tracy_zone.end(); @@ -2387,7 +2395,7 @@ fn isPositionBefore(lhs: types.Position, rhs: types.Position) bool { } } -fn inlayHintHandler(server: *Server, request: types.InlayHintParams) !?[]types.InlayHint { +fn inlayHintHandler(server: *Server, request: types.InlayHintParams) Error!?[]types.InlayHint { const tracy_zone = tracy.trace(@src()); defer tracy_zone.end(); @@ -2429,7 +2437,7 @@ fn inlayHintHandler(server: *Server, request: types.InlayHintParams) !?[]types.I return visible_hints; } -fn codeActionHandler(server: *Server, request: types.CodeActionParams) !?[]types.CodeAction { +fn codeActionHandler(server: *Server, request: types.CodeActionParams) Error!?[]types.CodeAction { const handle = server.document_store.getHandle(request.textDocument.uri) orelse return null; var builder = code_actions.Builder{ @@ -2442,7 +2450,10 @@ fn codeActionHandler(server: *Server, request: types.CodeActionParams) !?[]types // as of right now, only ast-check errors may get a code action var diagnostics = std.ArrayListUnmanaged(types.Diagnostic){}; if (server.config.enable_ast_check_diagnostics and handle.tree.errors.len == 0) { - try getAstCheckDiagnostics(server, handle.*, &diagnostics); + getAstCheckDiagnostics(server, handle.*, &diagnostics) catch |err| { + log.err("failed to run ast-check: {}", .{err}); + return error.InternalError; + }; } var actions = std.ArrayListUnmanaged(types.CodeAction){}; @@ -2453,7 +2464,7 @@ fn codeActionHandler(server: *Server, request: types.CodeActionParams) !?[]types return actions.items; } -fn foldingRangeHandler(server: *Server, request: types.FoldingRangeParams) !?[]types.FoldingRange { +fn foldingRangeHandler(server: *Server, request: types.FoldingRangeParams) Error!?[]types.FoldingRange { const Token = std.zig.Token; const Node = Ast.Node; const allocator = server.arena.allocator(); @@ -2716,7 +2727,7 @@ pub const SelectionRange = struct { parent: ?*SelectionRange, }; -fn selectionRangeHandler(server: *Server, request: types.SelectionRangeParams) !?[]*SelectionRange { +fn selectionRangeHandler(server: *Server, request: types.SelectionRangeParams) Error!?[]*SelectionRange { const allocator = server.arena.allocator(); const handle = server.document_store.getHandle(request.textDocument.uri) orelse return null; @@ -2906,26 +2917,23 @@ pub fn processJsonRpc( var parser = std.json.Parser.init(server.arena.allocator(), false); defer parser.deinit(); - var tree = parser.parse(json) catch { - log.err("failed to parse message!", .{}); + var tree = parser.parse(json) catch |err| { + log.err("failed to parse message: {}", .{err}); return; // maybe panic? }; defer tree.deinit(); - const message = Message.fromJsonValueTree(tree) catch { - log.err("failed to parse message!", .{}); + const message = Message.fromJsonValueTree(tree) catch |err| { + log.err("failed to parse message: {}", .{err}); return; // maybe panic? }; - server.processMessage(message) catch |err| { - log.err("got {} while processing message!", .{err}); // TODO include message information - switch (message) { - .RequestMessage => |request| server.sendResponseError(request.id, .{ - .code = @errorToInt(err), - .message = @errorName(err), - }), - else => {}, - } + server.processMessage(message) catch |err| switch (message) { + .RequestMessage => |request| server.sendResponseError(request.id, .{ + .code = @errorToInt(err), + .message = @errorName(err), + }), + else => {}, }; } @@ -3039,7 +3047,10 @@ fn processMessage(server: *Server, message: Message) Error!void { const ParamsType = handler_info.params[1].type.?; // TODO add error message on null const params: ParamsType = tres.parse(ParamsType, message.params().?, server.arena.allocator()) catch return error.InternalError; - const response = handler(server, params) catch return error.InternalError; + const response = handler(server, params) catch |err| { + log.err("got {} error while handling {s}", .{ err, method }); + return error.InternalError; + }; if (@TypeOf(response) == void) return; diff --git a/src/analysis.zig b/src/analysis.zig index 7c1879f..c7dca19 100644 --- a/src/analysis.zig +++ b/src/analysis.zig @@ -1680,7 +1680,7 @@ pub fn getPositionContext(allocator: std.mem.Allocator, text: []const u8, doc_in return if (tok.tag == .identifier) PositionContext{ .var_access = tok.loc } else .empty; } -fn addOutlineNodes(allocator: std.mem.Allocator, tree: Ast, child: Ast.Node.Index, context: *GetDocumentSymbolsContext) anyerror!void { +fn addOutlineNodes(allocator: std.mem.Allocator, tree: Ast, child: Ast.Node.Index, context: *GetDocumentSymbolsContext) error{OutOfMemory}!void { switch (tree.nodes.items(.tag)[child]) { .string_literal, .number_literal, @@ -1825,7 +1825,7 @@ const GetDocumentSymbolsContext = struct { encoding: offsets.Encoding, }; -fn getDocumentSymbolsInternal(allocator: std.mem.Allocator, tree: Ast, node: Ast.Node.Index, context: *GetDocumentSymbolsContext) anyerror!void { +fn getDocumentSymbolsInternal(allocator: std.mem.Allocator, tree: Ast, node: Ast.Node.Index, context: *GetDocumentSymbolsContext) error{OutOfMemory}!void { const name = getDeclName(tree, node) orelse return; if (name.len == 0) return; diff --git a/src/configuration.zig b/src/configuration.zig index ebab2e8..908b21c 100644 --- a/src/configuration.zig +++ b/src/configuration.zig @@ -240,4 +240,4 @@ pub fn findZig(allocator: std.mem.Allocator) !?[]const u8 { return try allocator.dupe(u8, full_path); } return null; -} \ No newline at end of file +} From 20baa592eb62fb49ae2127f2bcacc5da98072087 Mon Sep 17 00:00:00 2001 From: Auguste Rame <19855629+SuperAuguste@users.noreply.github.com> Date: Tue, 3 Jan 2023 10:37:59 -0500 Subject: [PATCH 02/24] Add error return trace (#882) --- src/Server.zig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Server.zig b/src/Server.zig index 265f823..c644004 100644 --- a/src/Server.zig +++ b/src/Server.zig @@ -3049,6 +3049,9 @@ fn processMessage(server: *Server, message: Message) Error!void { const params: ParamsType = tres.parse(ParamsType, message.params().?, server.arena.allocator()) catch return error.InternalError; const response = handler(server, params) catch |err| { log.err("got {} error while handling {s}", .{ err, method }); + if (@errorReturnTrace()) |trace| { + std.debug.dumpStackTrace(trace.*); + } return error.InternalError; }; From b163be51d36f3ac2c47c6da47052cbb971855b48 Mon Sep 17 00:00:00 2001 From: mlugg Date: Thu, 5 Jan 2023 18:50:02 +0000 Subject: [PATCH 03/24] Fix crash when using nvim-lspconfig (#884) Apparently, nvim reports its code action kinds using both the actual strings (e.g. "refactor.extract") and the enumeration names (e.g. "RefactorExtract"). I don't know why this is done - possibly an attempt at compatibility with non-compliant server implementations? Regardless, this was causing a crash on init (when tres tried to parse an initializaiton message), which is easily fixed by just supporting those enumeration values. Resolves: #867 --- src/lsp.zig | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/lsp.zig b/src/lsp.zig index 9585783..2b7fbcf 100644 --- a/src/lsp.zig +++ b/src/lsp.zig @@ -708,7 +708,29 @@ pub const CodeActionKind = enum { _ = maybe_allocator; if (json_value != .String) return error.InvalidEnumTag; if (json_value.String.len == 0) return .empty; - return std.meta.stringToEnum(@This(), json_value.String) orelse return error.InvalidEnumTag; + if (std.meta.stringToEnum(@This(), json_value.String)) |val| return val; + + // Some clients (nvim) may report these by the enumeration names rather than the + // actual strings, so let's check those names here + const aliases = [_]struct { []const u8, CodeActionKind }{ + .{ "Empty", .empty }, + .{ "QuickFix", .quickfix }, + .{ "Refactor", .refactor }, + .{ "RefactorExtract", .@"refactor.extract" }, + .{ "RefactorInline", .@"refactor.inline" }, + .{ "RefactorRewrite", .@"refactor.rewrite" }, + .{ "Source", .source }, + .{ "SourceOrganizeImports", .@"source.organizeImports" }, + .{ "SourceFixAll", .@"source.fixAll" }, + }; + + for (aliases) |alias| { + if (std.mem.eql(u8, json_value.String, alias[0])) { + return alias[1]; + } + } + + return error.InvalidEnumTag; } }; From 3f2700eaa525e00f7efeaaf057cd055d398df01d Mon Sep 17 00:00:00 2001 From: Techatrix <19954306+Techatrix@users.noreply.github.com> Date: Fri, 6 Jan 2023 18:59:20 +0000 Subject: [PATCH 04/24] improve completion on error and enums (#887) --- src/Server.zig | 37 +++++++++----- src/analysis.zig | 82 +++++++++++++++---------------- src/references.zig | 1 + tests/lsp_features/completion.zig | 48 +++++++++--------- 4 files changed, 89 insertions(+), 79 deletions(-) diff --git a/src/Server.zig b/src/Server.zig index c644004..6cd02b3 100644 --- a/src/Server.zig +++ b/src/Server.zig @@ -731,16 +731,14 @@ fn nodeToCompletion( .container_field_init, => { const field = ast.containerField(tree, node).?; - if (!field.ast.tuple_like) { - try list.append(allocator, .{ - .label = handle.tree.tokenSlice(field.ast.main_token), - .kind = .Field, - .documentation = doc, - .detail = analysis.getContainerFieldSignature(handle.tree, field), - .insertText = tree.tokenSlice(field.ast.main_token), - .insertTextFormat = .PlainText, - }); - } + try list.append(allocator, .{ + .label = handle.tree.tokenSlice(field.ast.main_token), + .kind = if (field.ast.tuple_like) .Enum else .Field, + .documentation = doc, + .detail = analysis.getContainerFieldSignature(handle.tree, field), + .insertText = tree.tokenSlice(field.ast.main_token), + .insertTextFormat = .PlainText, + }); }, .array_type, .array_type_sentinel, @@ -919,7 +917,13 @@ fn hoverSymbol(server: *Server, decl_handle: analysis.DeclWithHandle) error{OutO const end = offsets.tokenToLoc(tree, last_token).end; break :def tree.source[start..end]; }, - .pointer_payload, .array_payload, .array_index, .switch_payload, .label_decl => tree.tokenSlice(decl_handle.nameToken()), + .pointer_payload, + .array_payload, + .array_index, + .switch_payload, + .label_decl, + .error_token, + => tree.tokenSlice(decl_handle.nameToken()), }; var bound_type_params = analysis.BoundTypeParams{}; @@ -1223,6 +1227,17 @@ fn declToCompletion(context: DeclToCompletionContext, decl_handle: analysis.Decl .insertTextFormat = .PlainText, }); }, + .error_token => { + const name = tree.tokenSlice(decl_handle.decl.error_token); + + try context.completions.append(allocator, .{ + .label = name, + .kind = .Constant, + .detail = try std.fmt.allocPrint(allocator, "error.{s}", .{name}), + .insertText = name, + .insertTextFormat = .PlainText, + }); + }, } } diff --git a/src/analysis.zig b/src/analysis.zig index c7dca19..5b3ef86 100644 --- a/src/analysis.zig +++ b/src/analysis.zig @@ -292,9 +292,12 @@ pub fn getDeclNameToken(tree: Ast, node: Ast.Node.Index) ?Ast.TokenIndex { }, // containers - .container_field, .container_field_init, .container_field_align => { + .container_field, + .container_field_init, + .container_field_align, + => { const field = ast.containerField(tree, node).?.ast; - return if (field.tuple_like) null else field.main_token; + return field.main_token; }, .identifier => main_token, @@ -1937,6 +1940,8 @@ pub const Declaration = union(enum) { label: Ast.TokenIndex, block: Ast.Node.Index, }, + /// always an identifier + error_token: Ast.Node.Index, }; pub const DeclWithHandle = struct { @@ -1953,6 +1958,7 @@ pub const DeclWithHandle = struct { .array_index => |ai| ai, .switch_payload => |sp| sp.node, .label_decl => |ld| ld.label, + .error_token => |et| et, }; } @@ -2052,6 +2058,7 @@ pub const DeclWithHandle = struct { } return null; }, + .error_token => return null, }; } }; @@ -2395,6 +2402,7 @@ pub const DocumentScope = struct { } self.scopes.deinit(allocator); for (self.error_completions.entries.items(.key)) |item| { + if (item.detail) |detail| allocator.free(detail); switch (item.documentation orelse continue) { .string => |str| allocator.free(str), .MarkupContent => |content| allocator.free(content.value), @@ -2402,6 +2410,7 @@ pub const DocumentScope = struct { } self.error_completions.deinit(allocator); for (self.enum_completions.entries.items(.key)) |item| { + if (item.detail) |detail| allocator.free(detail); switch (item.documentation orelse continue) { .string => |str| allocator.free(str), .MarkupContent => |content| allocator.free(content.value), @@ -2475,9 +2484,6 @@ fn makeInnerScope(allocator: std.mem.Allocator, context: ScopeContext, node_idx: const main_tokens = tree.nodes.items(.main_token); const node_tag = tags[node_idx]; - var buf: [2]Ast.Node.Index = undefined; - const ast_decls = ast.declMembers(tree, node_idx, &buf); - var scope = try scopes.addOne(allocator); scope.* = .{ .loc = offsets.nodeToLoc(tree, node_idx), @@ -2490,26 +2496,26 @@ fn makeInnerScope(allocator: std.mem.Allocator, context: ScopeContext, node_idx: var i = main_tokens[node_idx]; while (i < data[node_idx].rhs) : (i += 1) { if (token_tags[i] == .identifier) { - try context.errors.put(allocator, .{ - .label = tree.tokenSlice(i), + const name = offsets.tokenToSlice(tree, i); + if (try scopes.items[scope_idx].decls.fetchPut(allocator, name, .{ .error_token = i })) |_| { + // TODO Record a redefinition error. + } + const gop = try context.errors.getOrPut(allocator, .{ + .label = name, .kind = .Constant, - .insertText = tree.tokenSlice(i), + //.detail = + .insertText = name, .insertTextFormat = .PlainText, - }, {}); + }); + if (!gop.found_existing) { + gop.key_ptr.detail = try std.fmt.allocPrint(allocator, "error.{s}", .{name}); + } } } } - var buffer: [2]Ast.Node.Index = undefined; - const container_decl = ast.containerDecl(tree, node_idx, &buffer); - - // Only tagged unions and enums should pass this - const can_have_enum_completions = if (container_decl) |container| blk: { - const kind = token_tags[container.ast.main_token]; - break :blk kind != .keyword_struct and - (kind != .keyword_union or container.ast.enum_token != null or container.ast.arg != 0); - } else false; - + var buf: [2]Ast.Node.Index = undefined; + const ast_decls = ast.declMembers(tree, node_idx, &buf); for (ast_decls) |decl| { if (tags[decl] == .@"usingnamespace") { try scopes.items[scope_idx].uses.append(allocator, decl); @@ -2528,31 +2534,23 @@ fn makeInnerScope(allocator: std.mem.Allocator, context: ScopeContext, node_idx: // TODO Record a redefinition error. } - if (!can_have_enum_completions) - continue; + var buffer: [2]Ast.Node.Index = undefined; + const container_decl = ast.containerDecl(tree, node_idx, &buffer) orelse continue; - const container_field = switch (tags[decl]) { - .container_field => tree.containerField(decl), - .container_field_align => tree.containerFieldAlign(decl), - .container_field_init => tree.containerFieldInit(decl), - else => null, - }; + if (container_decl.ast.enum_token != null) { + if (std.mem.eql(u8, name, "_")) return; + const Documentation = @TypeOf(@as(types.CompletionItem, undefined).documentation); - if (container_field) |_| { - if (!std.mem.eql(u8, name, "_")) { - const Documentation = @TypeOf(@as(types.CompletionItem, undefined).documentation); - - var doc: Documentation = if (try getDocComments(allocator, tree, decl, .markdown)) |docs| .{ .MarkupContent = types.MarkupContent{ .kind = .markdown, .value = docs } } else null; - var gop_res = try context.enums.getOrPut(allocator, .{ - .label = name, - .kind = .Constant, - .insertText = name, - .insertTextFormat = .PlainText, - .documentation = doc, - }); - if (gop_res.found_existing) { - if (doc) |d| allocator.free(d.MarkupContent.value); - } + var doc: Documentation = if (try getDocComments(allocator, tree, decl, .markdown)) |docs| .{ .MarkupContent = types.MarkupContent{ .kind = .markdown, .value = docs } } else null; + var gop_res = try context.enums.getOrPut(allocator, .{ + .label = name, + .kind = .Constant, + .insertText = name, + .insertTextFormat = .PlainText, + .documentation = doc, + }); + if (gop_res.found_existing) { + if (doc) |d| allocator.free(d.MarkupContent.value); } } } diff --git a/src/references.zig b/src/references.zig index bbdd5e3..e508ea9 100644 --- a/src/references.zig +++ b/src/references.zig @@ -534,6 +534,7 @@ pub fn symbolReferences( log.warn("Could not find param decl's function", .{}); }, .label_decl => unreachable, // handled separately by labelReferences + .error_token => {}, } return builder.locations; diff --git a/tests/lsp_features/completion.zig b/tests/lsp_features/completion.zig index 9f6ec86..968efdf 100644 --- a/tests/lsp_features/completion.zig +++ b/tests/lsp_features/completion.zig @@ -268,19 +268,16 @@ test "completion - union" { } test "completion - enum" { - // TODO: Fix - return error.SkipZigTest; - // try testCompletion( - // \\const E = enum { - // \\ alpha, - // \\ beta, - // \\}; - // \\const foo = E. - // , &.{ - // // TODO kind should be Enum - // .{ .label = "alpha", .kind = .Field }, - // .{ .label = "beta", .kind = .Field }, - // }); + try testCompletion( + \\const E = enum { + \\ alpha, + \\ beta, + \\}; + \\const foo = E. + , &.{ + .{ .label = "alpha", .kind = .Enum }, + .{ .label = "beta", .kind = .Enum }, + }); } test "completion - error union" { @@ -291,21 +288,20 @@ test "completion - error union" { \\}; \\const baz = error. , &.{ - .{ .label = "Foo", .kind = .Constant }, - .{ .label = "Bar", .kind = .Constant }, + .{ .label = "Foo", .kind = .Constant, .detail = "error.Foo" }, + .{ .label = "Bar", .kind = .Constant, .detail = "error.Bar" }, }); - // TODO implement completion for error unions - // try testCompletion( - // \\const E = error { - // \\ foo, - // \\ bar, - // \\}; - // \\const baz = E. - // , &.{ - // .{ .label = "foo", .kind = .Constant }, - // .{ .label = "bar", .kind = .Constant }, - // }); + try testCompletion( + \\const E = error { + \\ foo, + \\ bar, + \\}; + \\const baz = E. + , &.{ + .{ .label = "foo", .kind = .Constant, .detail = "error.foo" }, + .{ .label = "bar", .kind = .Constant, .detail = "error.bar" }, + }); try testCompletion( \\const S = struct { alpha: u32 }; From 2717b0fba19daba897f86dd6de4b8b590bfee516 Mon Sep 17 00:00:00 2001 From: Techatrix <19954306+Techatrix@users.noreply.github.com> Date: Fri, 6 Jan 2023 18:59:58 +0000 Subject: [PATCH 05/24] Verify minimum zig version at comptime (#885) * verify minimum zig version at comptime * run zig fmt --- build.zig | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/build.zig b/build.zig index d96dd1f..039f5fe 100644 --- a/build.zig +++ b/build.zig @@ -5,10 +5,13 @@ const shared = @import("src/shared.zig"); const zls_version = std.builtin.Version{ .major = 0, .minor = 11, .patch = 0 }; pub fn build(b: *std.build.Builder) !void { - const current_zig = builtin.zig_version; - const min_zig = std.SemanticVersion.parse("0.11.0-dev.874+40ed6ae84") catch return; // Changes to builtin.Type API - if (current_zig.order(min_zig).compare(.lt)) @panic(b.fmt("Your Zig version v{} does not meet the minimum build requirement of v{}", .{ current_zig, min_zig })); - + comptime { + const current_zig = builtin.zig_version; + const min_zig = std.SemanticVersion.parse("0.11.0-dev.874+40ed6ae84") catch return; // Changes to builtin.Type API + if (current_zig.order(min_zig) == .lt) { + @compileError(std.fmt.comptimePrint("Your Zig version v{} does not meet the minimum build requirement of v{}", .{ current_zig, min_zig })); + } + } const target = b.standardTargetOptions(.{}); const mode = b.standardReleaseOptions(); @@ -49,7 +52,7 @@ pub fn build(b: *std.build.Builder) !void { "enable_tracy_callstack", b.option(bool, "enable_tracy_callstack", "Enable callstack graphs.") orelse false, ); - + exe_options.addOption( bool, "enable_failing_allocator", From 20ba87c17375d34662f00bad6e481cb9b4f6864a Mon Sep 17 00:00:00 2001 From: erikarvstedt <36110478+erikarvstedt@users.noreply.github.com> Date: Sat, 7 Jan 2023 21:20:54 +0100 Subject: [PATCH 06/24] Fix Nix build, add Nix to CI (#840) * Nix: Reuse input `flake-utils` in `zig-overlay` * CI/main: convert line endings from `CRLF` to `LF` * CI: Add Nix build --- .github/workflows/main.yml | 257 ++++++++++++++++++++----------------- flake.lock | 19 +-- flake.nix | 1 + 3 files changed, 141 insertions(+), 136 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 21f7ebd..b135f1c 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,120 +1,137 @@ -name: CI - -on: - push: - paths: - - "**.zig" - pull_request: - paths: - - "**.zig" - schedule: - - cron: "0 0 * * *" - workflow_dispatch: - -jobs: - build: - strategy: - matrix: - os: [ubuntu-latest, macos-latest, windows-latest] - runs-on: ${{ matrix.os }} - steps: - - uses: actions/checkout@v3 - with: - fetch-depth: 0 - submodules: true - - uses: goto-bus-stop/setup-zig@v2 - with: - version: master - - - run: zig version - - run: zig env - - - name: Build - run: zig build - - - name: Build with Tracy - if: ${{ matrix.os != 'macos-latest' }} - run: zig build -Denable_tracy -Denable_tracy_allocation - - - name: Run Tests - run: zig build test - - - name: Build artifacts - if: ${{ matrix.os == 'ubuntu-latest' }} - run: | - declare -a targets=("x86_64-windows" "x86_64-linux" "x86_64-macos" "x86-windows" "x86-linux" "aarch64-linux" "aarch64-macos") - mkdir -p "artifacts/" - - for target in "${targets[@]}"; do - mkdir -p artifacts/$target - echo "Building target ${target}..." - if [ "${GITHUB_REF##*/}" == "master" ]; then - echo "Building safe" - zig build -Dtarget=${target} -Drelease-safe --prefix artifacts/${target}/ - else - echo "Building debug as action is not running on master" - zig build -Dtarget=${target} --prefix artifacts/${target}/ - fi - sed -e '1,5d' < README.md > artifacts/${target}/README.md - cp LICENSE artifacts/${target}/ - done - - - name: Upload x86_64-windows artifact - if: ${{ matrix.os == 'ubuntu-latest' }} - uses: actions/upload-artifact@v3 - with: - name: zls-x86_64-windows - path: artifacts/x86_64-windows/ - - - name: Upload x86_64-linux artifact - if: ${{ matrix.os == 'ubuntu-latest' }} - uses: actions/upload-artifact@v3 - with: - name: zls-x86_64-linux - path: artifacts/x86_64-linux/ - - - name: Upload x86_64-macos artifact - if: ${{ matrix.os == 'ubuntu-latest' }} - uses: actions/upload-artifact@v3 - with: - name: zls-x86_64-macos - path: artifacts/x86_64-macos/ - - - name: Upload x86-windows artifact - if: ${{ matrix.os == 'ubuntu-latest' }} - uses: actions/upload-artifact@v3 - with: - name: zls-x86-windows - path: artifacts/x86-windows/ - - - name: Upload x86-linux artifact - if: ${{ matrix.os == 'ubuntu-latest' }} - uses: actions/upload-artifact@v3 - with: - name: zls-x86-linux - path: artifacts/x86-linux/ - - - name: Upload aarch64-linux artifact - if: ${{ matrix.os == 'ubuntu-latest' }} - uses: actions/upload-artifact@v3 - with: - name: zls-aarch64-linux - path: artifacts/aarch64-linux/ - - - name: Upload aarch64-macos artifact - if: ${{ matrix.os == 'ubuntu-latest' }} - uses: actions/upload-artifact@v3 - with: - name: zls-aarch64-macos - path: artifacts/aarch64-macos/ - - - name: Beam to Felix - if: ${{ matrix.os == 'ubuntu-latest' && github.ref == 'refs/heads/master' && github.repository_owner == 'zigtools' }} - uses: easingthemes/ssh-deploy@v2.1.1 - env: - SSH_PRIVATE_KEY: ${{ secrets.SERVER_SSH_PRIVKEY }} - ARGS: "-rltgoDzvO --delete" - SOURCE: "artifacts/" - REMOTE_HOST: ${{ secrets.WEBSITE_DEPLOY_HOST }} - REMOTE_USER: ${{ secrets.WEBSITE_DEPLOY_USER }} - TARGET: ${{ secrets.WEBSITE_DEPLOY_FOLDER }} +name: CI + +on: + push: + paths: + - "**.zig" + - "flake.*" + pull_request: + paths: + - "**.zig" + - "flake.*" + schedule: + - cron: "0 0 * * *" + workflow_dispatch: + +jobs: + build: + strategy: + matrix: + os: [ubuntu-latest, macos-latest, windows-latest] + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + submodules: true + - uses: goto-bus-stop/setup-zig@v2 + with: + version: master + + - run: zig version + - run: zig env + + - name: Build + run: zig build + + - name: Build with Tracy + if: ${{ matrix.os != 'macos-latest' }} + run: zig build -Denable_tracy -Denable_tracy_allocation + + - name: Run Tests + run: zig build test + + - name: Build artifacts + if: ${{ matrix.os == 'ubuntu-latest' }} + run: | + declare -a targets=("x86_64-windows" "x86_64-linux" "x86_64-macos" "x86-windows" "x86-linux" "aarch64-linux" "aarch64-macos") + mkdir -p "artifacts/" + + for target in "${targets[@]}"; do + mkdir -p artifacts/$target + echo "Building target ${target}..." + if [ "${GITHUB_REF##*/}" == "master" ]; then + echo "Building safe" + zig build -Dtarget=${target} -Drelease-safe --prefix artifacts/${target}/ + else + echo "Building debug as action is not running on master" + zig build -Dtarget=${target} --prefix artifacts/${target}/ + fi + sed -e '1,5d' < README.md > artifacts/${target}/README.md + cp LICENSE artifacts/${target}/ + done + + - name: Upload x86_64-windows artifact + if: ${{ matrix.os == 'ubuntu-latest' }} + uses: actions/upload-artifact@v3 + with: + name: zls-x86_64-windows + path: artifacts/x86_64-windows/ + + - name: Upload x86_64-linux artifact + if: ${{ matrix.os == 'ubuntu-latest' }} + uses: actions/upload-artifact@v3 + with: + name: zls-x86_64-linux + path: artifacts/x86_64-linux/ + + - name: Upload x86_64-macos artifact + if: ${{ matrix.os == 'ubuntu-latest' }} + uses: actions/upload-artifact@v3 + with: + name: zls-x86_64-macos + path: artifacts/x86_64-macos/ + + - name: Upload x86-windows artifact + if: ${{ matrix.os == 'ubuntu-latest' }} + uses: actions/upload-artifact@v3 + with: + name: zls-x86-windows + path: artifacts/x86-windows/ + + - name: Upload x86-linux artifact + if: ${{ matrix.os == 'ubuntu-latest' }} + uses: actions/upload-artifact@v3 + with: + name: zls-x86-linux + path: artifacts/x86-linux/ + + - name: Upload aarch64-linux artifact + if: ${{ matrix.os == 'ubuntu-latest' }} + uses: actions/upload-artifact@v3 + with: + name: zls-aarch64-linux + path: artifacts/aarch64-linux/ + + - name: Upload aarch64-macos artifact + if: ${{ matrix.os == 'ubuntu-latest' }} + uses: actions/upload-artifact@v3 + with: + name: zls-aarch64-macos + path: artifacts/aarch64-macos/ + + - name: Beam to Felix + if: ${{ matrix.os == 'ubuntu-latest' && github.ref == 'refs/heads/master' && github.repository_owner == 'zigtools' }} + uses: easingthemes/ssh-deploy@v2.1.1 + env: + SSH_PRIVATE_KEY: ${{ secrets.SERVER_SSH_PRIVKEY }} + ARGS: "-rltgoDzvO --delete" + SOURCE: "artifacts/" + REMOTE_HOST: ${{ secrets.WEBSITE_DEPLOY_HOST }} + REMOTE_USER: ${{ secrets.WEBSITE_DEPLOY_USER }} + TARGET: ${{ secrets.WEBSITE_DEPLOY_FOLDER }} + + - name: Install Nix + if: ${{ matrix.os == 'ubuntu-latest' }} + uses: cachix/install-nix-action@v18 + + - name: Install Cachix + if: ${{ matrix.os == 'ubuntu-latest' }} + uses: cachix/cachix-action@v12 + with: + name: zigtools + authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' + + - name: Build Nix flake package + if: ${{ matrix.os == 'ubuntu-latest' }} + run: nix build --print-build-logs diff --git a/flake.lock b/flake.lock index 21f8a55..9a93c55 100644 --- a/flake.lock +++ b/flake.lock @@ -1,21 +1,6 @@ { "nodes": { "flake-utils": { - "locked": { - "lastModified": 1667395993, - "narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, - "flake-utils_2": { "locked": { "lastModified": 1659877975, "narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=", @@ -110,7 +95,9 @@ }, "zig-overlay": { "inputs": { - "flake-utils": "flake-utils_2", + "flake-utils": [ + "flake-utils" + ], "nixpkgs": [ "nixpkgs" ] diff --git a/flake.nix b/flake.nix index 4a44b2e..00e9114 100644 --- a/flake.nix +++ b/flake.nix @@ -4,6 +4,7 @@ zig-overlay.url = "github:mitchellh/zig-overlay"; zig-overlay.inputs.nixpkgs.follows = "nixpkgs"; + zig-overlay.inputs.flake-utils.follows = "flake-utils"; gitignore.url = "github:hercules-ci/gitignore.nix"; gitignore.inputs.nixpkgs.follows = "nixpkgs"; From 54e7d1da8b6beb5d37a2a04abb6a77bd8c60b10f Mon Sep 17 00:00:00 2001 From: Techatrix <19954306+Techatrix@users.noreply.github.com> Date: Sat, 7 Jan 2023 20:21:20 +0000 Subject: [PATCH 07/24] fix compile errors when targeting wasm (#886) * fix compile errors when targeting wasm * update known-folders --- src/DocumentStore.zig | 10 +++++++--- src/Server.zig | 16 +++++++++++----- src/configuration.zig | 1 + src/known-folders | 2 +- 4 files changed, 20 insertions(+), 9 deletions(-) diff --git a/src/DocumentStore.zig b/src/DocumentStore.zig index 318bd1a..4f1f04f 100644 --- a/src/DocumentStore.zig +++ b/src/DocumentStore.zig @@ -224,7 +224,7 @@ pub fn applySave(self: *DocumentStore, handle: *const Handle) !void { const tracy_zone = tracy.trace(@src()); defer tracy_zone.end(); - if (isBuildFile(handle.uri)) { + if (std.process.can_spawn and isBuildFile(handle.uri)) { const build_file = self.build_files.getPtr(handle.uri).?; const build_config = loadBuildConfiguration(self.allocator, build_file.*, self.config.*) catch |err| { @@ -647,7 +647,9 @@ fn createDocument(self: *DocumentStore, uri: Uri, text: [:0]u8, open: bool) erro handle.import_uris = try self.collectImportUris(handle); handle.cimports = try self.collectCIncludes(handle); - if (self.config.zig_exe_path != null and isBuildFile(handle.uri) and !isInStd(handle.uri)) { + if (!std.process.can_spawn or self.config.zig_exe_path == null) return handle; + + if (isBuildFile(handle.uri) and !isInStd(handle.uri)) { const gop = try self.build_files.getOrPut(self.allocator, uri); errdefer |err| { self.build_files.swapRemoveAt(gop.index); @@ -658,7 +660,7 @@ fn createDocument(self: *DocumentStore, uri: Uri, text: [:0]u8, open: bool) erro gop.value_ptr.* = try self.createBuildFile(duped_uri); gop.key_ptr.* = gop.value_ptr.uri; } - } else if (self.config.zig_exe_path != null and !isBuiltinFile(handle.uri) and !isInStd(handle.uri)) blk: { + } else if (!isBuiltinFile(handle.uri) and !isInStd(handle.uri)) blk: { // log.debug("Going to walk down the tree towards: {s}", .{uri}); // walk down the tree towards the uri. When we hit build.zig files @@ -831,6 +833,8 @@ pub fn resolveCImport(self: *DocumentStore, handle: Handle, node: Ast.Node.Index const tracy_zone = tracy.trace(@src()); defer tracy_zone.end(); + if (!std.process.can_spawn) return null; + const index = std.mem.indexOfScalar(Ast.Node.Index, handle.cimports.items(.node), node).?; const hash: Hash = handle.cimports.items(.hash)[index]; diff --git a/src/Server.zig b/src/Server.zig index 6cd02b3..728f4f5 100644 --- a/src/Server.zig +++ b/src/Server.zig @@ -1712,6 +1712,7 @@ fn initializeHandler(server: *Server, request: types.InitializeParams) Error!typ server.status = .initializing; if (server.config.zig_exe_path) |exe_path| blk: { + if (!std.process.can_spawn) break :blk; // TODO avoid having to call getZigEnv twice // once in init and here const env = configuration.getZigEnv(server.allocator, exe_path) orelse break :blk; @@ -1962,7 +1963,8 @@ fn openDocumentHandler(server: *Server, notification: types.DidOpenTextDocumentP const handle = try server.document_store.openDocument(notification.textDocument.uri, notification.textDocument.text); - if (server.client_capabilities.supports_publish_diagnostics) { + if (server.client_capabilities.supports_publish_diagnostics) blk: { + if (!std.process.can_spawn) break :blk; const diagnostics = try server.generateDiagnostics(handle); server.sendNotification("textDocument/publishDiagnostics", diagnostics); } @@ -1978,7 +1980,8 @@ fn changeDocumentHandler(server: *Server, notification: types.DidChangeTextDocum try server.document_store.refreshDocument(handle.uri, new_text); - if (server.client_capabilities.supports_publish_diagnostics) { + if (server.client_capabilities.supports_publish_diagnostics) blk: { + if (!std.process.can_spawn) break :blk; const diagnostics = try server.generateDiagnostics(handle.*); server.sendNotification("textDocument/publishDiagnostics", diagnostics); } @@ -1994,7 +1997,7 @@ fn saveDocumentHandler(server: *Server, notification: types.DidSaveTextDocumentP const handle = server.document_store.getHandle(uri) orelse return; try server.document_store.applySave(handle); - if (server.getAutofixMode() == .on_save) { + if (std.process.can_spawn and server.getAutofixMode() == .on_save) { var text_edits = try server.autofix(allocator, handle); var workspace_edit = types.WorkspaceEdit{ .changes = .{} }; @@ -2028,6 +2031,7 @@ fn willSaveWaitUntilHandler(server: *Server, request: types.WillSaveTextDocument const handle = server.document_store.getHandle(request.textDocument.uri) orelse return null; + if (!std.process.can_spawn) return null; var text_edits = try server.autofix(allocator, handle); return try text_edits.toOwnedSlice(allocator); @@ -2192,7 +2196,8 @@ fn hoverHandler(server: *Server, request: types.HoverParams) Error!?types.Hover }; // TODO: Figure out a better solution for comptime interpreter diags - if (server.client_capabilities.supports_publish_diagnostics) { + if (server.client_capabilities.supports_publish_diagnostics) blk: { + if (!std.process.can_spawn) break :blk; const diagnostics = try server.generateDiagnostics(handle.*); server.sendNotification("textDocument/publishDiagnostics", diagnostics); } @@ -2464,7 +2469,8 @@ fn codeActionHandler(server: *Server, request: types.CodeActionParams) Error!?[] // as of right now, only ast-check errors may get a code action var diagnostics = std.ArrayListUnmanaged(types.Diagnostic){}; - if (server.config.enable_ast_check_diagnostics and handle.tree.errors.len == 0) { + if (server.config.enable_ast_check_diagnostics and handle.tree.errors.len == 0) blk: { + if (!std.process.can_spawn) break :blk; getAstCheckDiagnostics(server, handle.*, &diagnostics) catch |err| { log.err("failed to run ast-check: {}", .{err}); return error.InternalError; diff --git a/src/configuration.zig b/src/configuration.zig index 908b21c..b7f00d3 100644 --- a/src/configuration.zig +++ b/src/configuration.zig @@ -55,6 +55,7 @@ pub fn loadFromFolder(allocator: std.mem.Allocator, folder_path: []const u8) ?Co /// Invoke this once all config values have been changed. pub fn configChanged(config: *Config, allocator: std.mem.Allocator, builtin_creation_dir: ?[]const u8) !void { + if (!std.process.can_spawn) return; // Find the zig executable in PATH find_zig: { if (config.zig_exe_path) |exe_path| { diff --git a/src/known-folders b/src/known-folders index 24845b0..6b37490 160000 --- a/src/known-folders +++ b/src/known-folders @@ -1 +1 @@ -Subproject commit 24845b0103e611c108d6bc334231c464e699742c +Subproject commit 6b37490ac7285133bf09441850b8102c9728a776 From e9b364772df065b292522da0831177a42e60d31a Mon Sep 17 00:00:00 2001 From: Techatrix <19954306+Techatrix@users.noreply.github.com> Date: Sat, 7 Jan 2023 21:33:10 +0000 Subject: [PATCH 08/24] fix returning freed memory in formattingHandler (#890) --- src/Server.zig | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/Server.zig b/src/Server.zig index 728f4f5..0887253 100644 --- a/src/Server.zig +++ b/src/Server.zig @@ -2222,13 +2222,14 @@ fn formattingHandler(server: *Server, request: types.DocumentFormattingParams) E if (handle.tree.errors.len != 0) return null; - const formatted = try handle.tree.render(server.allocator); - defer server.allocator.free(formatted); + const allocator = server.arena.allocator(); + + const formatted = try handle.tree.render(allocator); if (std.mem.eql(u8, handle.text, formatted)) return null; // avoid computing diffs if the output is small - const maybe_edits = if (formatted.len <= 512) null else diff.edits(server.arena.allocator(), handle.text, formatted) catch null; + const maybe_edits = if (formatted.len <= 512) null else diff.edits(allocator, handle.text, formatted) catch null; const edits = maybe_edits orelse { // if edits have been computed we replace the entire file with the formatted text @@ -2239,7 +2240,7 @@ fn formattingHandler(server: *Server, request: types.DocumentFormattingParams) E }; // Convert from `[]diff.Edit` to `[]types.TextEdit` - var text_edits = try std.ArrayListUnmanaged(types.TextEdit).initCapacity(server.arena.allocator(), edits.items.len); + var text_edits = try std.ArrayListUnmanaged(types.TextEdit).initCapacity(allocator, edits.items.len); for (edits.items) |edit| { text_edits.appendAssumeCapacity(.{ .range = edit.range, From 48288e02a9a5d0ba4ef5be1db7be6a64d37d2806 Mon Sep 17 00:00:00 2001 From: Auguste Rame <19855629+SuperAuguste@users.noreply.github.com> Date: Sat, 7 Jan 2023 18:14:45 -0500 Subject: [PATCH 09/24] Revert "Fix Nix build, add Nix to CI (#840)" (#893) This reverts commit 20ba87c17375d34662f00bad6e481cb9b4f6864a. --- .github/workflows/main.yml | 257 +++++++++++++++++-------------------- flake.lock | 19 ++- flake.nix | 1 - 3 files changed, 136 insertions(+), 141 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index b135f1c..21f7ebd 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,137 +1,120 @@ -name: CI - -on: - push: - paths: - - "**.zig" - - "flake.*" - pull_request: - paths: - - "**.zig" - - "flake.*" - schedule: - - cron: "0 0 * * *" - workflow_dispatch: - -jobs: - build: - strategy: - matrix: - os: [ubuntu-latest, macos-latest, windows-latest] - runs-on: ${{ matrix.os }} - steps: - - uses: actions/checkout@v3 - with: - fetch-depth: 0 - submodules: true - - uses: goto-bus-stop/setup-zig@v2 - with: - version: master - - - run: zig version - - run: zig env - - - name: Build - run: zig build - - - name: Build with Tracy - if: ${{ matrix.os != 'macos-latest' }} - run: zig build -Denable_tracy -Denable_tracy_allocation - - - name: Run Tests - run: zig build test - - - name: Build artifacts - if: ${{ matrix.os == 'ubuntu-latest' }} - run: | - declare -a targets=("x86_64-windows" "x86_64-linux" "x86_64-macos" "x86-windows" "x86-linux" "aarch64-linux" "aarch64-macos") - mkdir -p "artifacts/" - - for target in "${targets[@]}"; do - mkdir -p artifacts/$target - echo "Building target ${target}..." - if [ "${GITHUB_REF##*/}" == "master" ]; then - echo "Building safe" - zig build -Dtarget=${target} -Drelease-safe --prefix artifacts/${target}/ - else - echo "Building debug as action is not running on master" - zig build -Dtarget=${target} --prefix artifacts/${target}/ - fi - sed -e '1,5d' < README.md > artifacts/${target}/README.md - cp LICENSE artifacts/${target}/ - done - - - name: Upload x86_64-windows artifact - if: ${{ matrix.os == 'ubuntu-latest' }} - uses: actions/upload-artifact@v3 - with: - name: zls-x86_64-windows - path: artifacts/x86_64-windows/ - - - name: Upload x86_64-linux artifact - if: ${{ matrix.os == 'ubuntu-latest' }} - uses: actions/upload-artifact@v3 - with: - name: zls-x86_64-linux - path: artifacts/x86_64-linux/ - - - name: Upload x86_64-macos artifact - if: ${{ matrix.os == 'ubuntu-latest' }} - uses: actions/upload-artifact@v3 - with: - name: zls-x86_64-macos - path: artifacts/x86_64-macos/ - - - name: Upload x86-windows artifact - if: ${{ matrix.os == 'ubuntu-latest' }} - uses: actions/upload-artifact@v3 - with: - name: zls-x86-windows - path: artifacts/x86-windows/ - - - name: Upload x86-linux artifact - if: ${{ matrix.os == 'ubuntu-latest' }} - uses: actions/upload-artifact@v3 - with: - name: zls-x86-linux - path: artifacts/x86-linux/ - - - name: Upload aarch64-linux artifact - if: ${{ matrix.os == 'ubuntu-latest' }} - uses: actions/upload-artifact@v3 - with: - name: zls-aarch64-linux - path: artifacts/aarch64-linux/ - - - name: Upload aarch64-macos artifact - if: ${{ matrix.os == 'ubuntu-latest' }} - uses: actions/upload-artifact@v3 - with: - name: zls-aarch64-macos - path: artifacts/aarch64-macos/ - - - name: Beam to Felix - if: ${{ matrix.os == 'ubuntu-latest' && github.ref == 'refs/heads/master' && github.repository_owner == 'zigtools' }} - uses: easingthemes/ssh-deploy@v2.1.1 - env: - SSH_PRIVATE_KEY: ${{ secrets.SERVER_SSH_PRIVKEY }} - ARGS: "-rltgoDzvO --delete" - SOURCE: "artifacts/" - REMOTE_HOST: ${{ secrets.WEBSITE_DEPLOY_HOST }} - REMOTE_USER: ${{ secrets.WEBSITE_DEPLOY_USER }} - TARGET: ${{ secrets.WEBSITE_DEPLOY_FOLDER }} - - - name: Install Nix - if: ${{ matrix.os == 'ubuntu-latest' }} - uses: cachix/install-nix-action@v18 - - - name: Install Cachix - if: ${{ matrix.os == 'ubuntu-latest' }} - uses: cachix/cachix-action@v12 - with: - name: zigtools - authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' - - - name: Build Nix flake package - if: ${{ matrix.os == 'ubuntu-latest' }} - run: nix build --print-build-logs +name: CI + +on: + push: + paths: + - "**.zig" + pull_request: + paths: + - "**.zig" + schedule: + - cron: "0 0 * * *" + workflow_dispatch: + +jobs: + build: + strategy: + matrix: + os: [ubuntu-latest, macos-latest, windows-latest] + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + submodules: true + - uses: goto-bus-stop/setup-zig@v2 + with: + version: master + + - run: zig version + - run: zig env + + - name: Build + run: zig build + + - name: Build with Tracy + if: ${{ matrix.os != 'macos-latest' }} + run: zig build -Denable_tracy -Denable_tracy_allocation + + - name: Run Tests + run: zig build test + + - name: Build artifacts + if: ${{ matrix.os == 'ubuntu-latest' }} + run: | + declare -a targets=("x86_64-windows" "x86_64-linux" "x86_64-macos" "x86-windows" "x86-linux" "aarch64-linux" "aarch64-macos") + mkdir -p "artifacts/" + + for target in "${targets[@]}"; do + mkdir -p artifacts/$target + echo "Building target ${target}..." + if [ "${GITHUB_REF##*/}" == "master" ]; then + echo "Building safe" + zig build -Dtarget=${target} -Drelease-safe --prefix artifacts/${target}/ + else + echo "Building debug as action is not running on master" + zig build -Dtarget=${target} --prefix artifacts/${target}/ + fi + sed -e '1,5d' < README.md > artifacts/${target}/README.md + cp LICENSE artifacts/${target}/ + done + + - name: Upload x86_64-windows artifact + if: ${{ matrix.os == 'ubuntu-latest' }} + uses: actions/upload-artifact@v3 + with: + name: zls-x86_64-windows + path: artifacts/x86_64-windows/ + + - name: Upload x86_64-linux artifact + if: ${{ matrix.os == 'ubuntu-latest' }} + uses: actions/upload-artifact@v3 + with: + name: zls-x86_64-linux + path: artifacts/x86_64-linux/ + + - name: Upload x86_64-macos artifact + if: ${{ matrix.os == 'ubuntu-latest' }} + uses: actions/upload-artifact@v3 + with: + name: zls-x86_64-macos + path: artifacts/x86_64-macos/ + + - name: Upload x86-windows artifact + if: ${{ matrix.os == 'ubuntu-latest' }} + uses: actions/upload-artifact@v3 + with: + name: zls-x86-windows + path: artifacts/x86-windows/ + + - name: Upload x86-linux artifact + if: ${{ matrix.os == 'ubuntu-latest' }} + uses: actions/upload-artifact@v3 + with: + name: zls-x86-linux + path: artifacts/x86-linux/ + + - name: Upload aarch64-linux artifact + if: ${{ matrix.os == 'ubuntu-latest' }} + uses: actions/upload-artifact@v3 + with: + name: zls-aarch64-linux + path: artifacts/aarch64-linux/ + + - name: Upload aarch64-macos artifact + if: ${{ matrix.os == 'ubuntu-latest' }} + uses: actions/upload-artifact@v3 + with: + name: zls-aarch64-macos + path: artifacts/aarch64-macos/ + + - name: Beam to Felix + if: ${{ matrix.os == 'ubuntu-latest' && github.ref == 'refs/heads/master' && github.repository_owner == 'zigtools' }} + uses: easingthemes/ssh-deploy@v2.1.1 + env: + SSH_PRIVATE_KEY: ${{ secrets.SERVER_SSH_PRIVKEY }} + ARGS: "-rltgoDzvO --delete" + SOURCE: "artifacts/" + REMOTE_HOST: ${{ secrets.WEBSITE_DEPLOY_HOST }} + REMOTE_USER: ${{ secrets.WEBSITE_DEPLOY_USER }} + TARGET: ${{ secrets.WEBSITE_DEPLOY_FOLDER }} diff --git a/flake.lock b/flake.lock index 9a93c55..21f8a55 100644 --- a/flake.lock +++ b/flake.lock @@ -1,6 +1,21 @@ { "nodes": { "flake-utils": { + "locked": { + "lastModified": 1667395993, + "narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_2": { "locked": { "lastModified": 1659877975, "narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=", @@ -95,9 +110,7 @@ }, "zig-overlay": { "inputs": { - "flake-utils": [ - "flake-utils" - ], + "flake-utils": "flake-utils_2", "nixpkgs": [ "nixpkgs" ] diff --git a/flake.nix b/flake.nix index 00e9114..4a44b2e 100644 --- a/flake.nix +++ b/flake.nix @@ -4,7 +4,6 @@ zig-overlay.url = "github:mitchellh/zig-overlay"; zig-overlay.inputs.nixpkgs.follows = "nixpkgs"; - zig-overlay.inputs.flake-utils.follows = "flake-utils"; gitignore.url = "github:hercules-ci/gitignore.nix"; gitignore.inputs.nixpkgs.follows = "nixpkgs"; From 68790c73a771d09855d575df4ad77eb1799a0da9 Mon Sep 17 00:00:00 2001 From: Techatrix <19954306+Techatrix@users.noreply.github.com> Date: Mon, 9 Jan 2023 04:13:02 +0000 Subject: [PATCH 10/24] return from main instead of calling exit (#894) --- src/Server.zig | 24 +++++++++++++----------- src/main.zig | 6 ++++++ 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/src/Server.zig b/src/Server.zig index 0887253..304f35f 100644 --- a/src/Server.zig +++ b/src/Server.zig @@ -49,6 +49,10 @@ status: enum { initialized, /// the server has been shutdown and can't handle any more requests shutdown, + /// the server is received a `exit` notification and has been shutdown + exiting_success, + /// the server is received a `exit` notification but has not been shutdown + exiting_failure, }, // Code was based off of https://github.com/andersfr/zig-lsp/blob/master/server.zig @@ -1827,22 +1831,18 @@ fn initializedHandler(server: *Server, notification: types.InitializedParams) Er } fn shutdownHandler(server: *Server, _: void) Error!?void { + defer server.status = .shutdown; if (server.status != .initialized) return error.InvalidRequest; // received a shutdown request but the server is not initialized! - // Technically we should deinitialize first and send possible errors to the client return null; } -fn exitHandler(server: *Server, _: void) noreturn { - log.info("Server exiting...", .{}); - // Technically we should deinitialize first and send possible errors to the client - - const error_code: u8 = switch (server.status) { - .uninitialized, .shutdown => 0, - else => 1, +fn exitHandler(server: *Server, _: void) Error!void { + server.status = switch (server.status) { + .initialized => .exiting_failure, + .shutdown => .exiting_success, + else => unreachable, }; - - std.os.exit(error_code); } fn cancelRequestHandler(server: *Server, request: types.CancelParams) Error!void { @@ -3007,12 +3007,14 @@ fn processMessage(server: *Server, message: Message) Error!void { return error.InvalidRequest; // server received a request after shutdown! }, + .exiting_success, + .exiting_failure, => unreachable, } const start_time = std.time.milliTimestamp(); defer { // makes `zig build test` look nice - if (!zig_builtin.is_test and !std.mem.eql(u8, method, "shutdown")) { + if (!zig_builtin.is_test) { const end_time = std.time.milliTimestamp(); log.debug("Took {}ms to process method {s}", .{ end_time - start_time, method }); } diff --git a/src/main.zig b/src/main.zig index e4f3407..556492d 100644 --- a/src/main.zig +++ b/src/main.zig @@ -76,6 +76,8 @@ fn loop( } server.processJsonRpc(&arena, json_message); + + if(server.status == .exiting_success or server.status == .exiting_failure) return; } } @@ -387,4 +389,8 @@ pub fn main() !void { defer server.deinit(); try loop(&server, record_file, replay_file); + + if (server.status == .exiting_failure) { + std.process.exit(1); + } } From 21b103c15832bebcc5bafa3873e0cac9317898f3 Mon Sep 17 00:00:00 2001 From: Auguste Rame <19855629+SuperAuguste@users.noreply.github.com> Date: Sun, 8 Jan 2023 23:13:20 -0500 Subject: [PATCH 11/24] Fix build runner cwd causing relative @src (#898) Co-authored-by: Nameless Co-authored-by: Nameless --- src/DocumentStore.zig | 1 + 1 file changed, 1 insertion(+) diff --git a/src/DocumentStore.zig b/src/DocumentStore.zig index 4f1f04f..ec72988 100644 --- a/src/DocumentStore.zig +++ b/src/DocumentStore.zig @@ -431,6 +431,7 @@ fn loadBuildConfiguration( const zig_run_result = try std.ChildProcess.exec(.{ .allocator = arena_allocator, .argv = args.items, + .cwd = try std.fs.path.resolve(arena_allocator, &.{ config.zig_exe_path.?, "../" }), }); defer { From 4423a5face882217925bb0f138d9c7fec6d0430b Mon Sep 17 00:00:00 2001 From: Techatrix <19954306+Techatrix@users.noreply.github.com> Date: Mon, 9 Jan 2023 16:09:36 +0000 Subject: [PATCH 12/24] improve memory allocations (#889) * improve memory allocations * Update src/main.zig Co-authored-by: erikarvstedt <36110478+erikarvstedt@users.noreply.github.com> * add missing 0x21 Co-authored-by: erikarvstedt <36110478+erikarvstedt@users.noreply.github.com> --- src/Server.zig | 6 +++--- src/main.zig | 15 ++++++++++++--- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/Server.zig b/src/Server.zig index 304f35f..975409b 100644 --- a/src/Server.zig +++ b/src/Server.zig @@ -1334,7 +1334,7 @@ fn completeFieldAccess(server: *Server, handle: *const DocumentStore.Handle, sou return try completions.toOwnedSlice(allocator); } -fn formatDetailledLabel(item: *types.CompletionItem, alloc: std.mem.Allocator) error{OutOfMemory}!void { +fn formatDetailledLabel(item: *types.CompletionItem, arena: std.mem.Allocator) error{OutOfMemory}!void { // NOTE: this is not ideal, we should build a detailled label like we do for label/detail // because this implementation is very loose, nothing is formated properly so we need to clean // things a little bit, wich is quite messy @@ -1345,7 +1345,7 @@ fn formatDetailledLabel(item: *types.CompletionItem, alloc: std.mem.Allocator) e return; var detailLen: usize = item.detail.?.len; - var it: []u8 = try alloc.alloc(u8, detailLen); + var it: []u8 = try arena.alloc(u8, detailLen); detailLen -= std.mem.replace(u8, item.detail.?, " ", " ", it) * 3; it = it[0..detailLen]; @@ -1695,7 +1695,7 @@ fn initializeHandler(server: *Server, request: types.InitializeParams) Error!typ // so we can now format the prebuilt builtins items for labelDetails if (server.client_capabilities.label_details_support) { for (server.builtin_completions.items) |*item| { - try formatDetailledLabel(item, std.heap.page_allocator); + try formatDetailledLabel(item, server.arena.allocator()); } } diff --git a/src/main.zig b/src/main.zig index 556492d..812f40b 100644 --- a/src/main.zig +++ b/src/main.zig @@ -48,9 +48,18 @@ fn loop( var buffered_writer = std.io.bufferedWriter(std_out); const writer = buffered_writer.writer(); + var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator); + defer arena.deinit(); + while (true) { - var arena = std.heap.ArenaAllocator.init(server.allocator); - defer arena.deinit(); + defer { + // Mom, can we have garbage collection? + // No, we already have garbage collection at home. + // at home: + if (arena.queryCapacity() > 128 * 1024) { + _ = arena.reset(.free_all); + } + } // write server -> client messages for (server.outgoing_messages.items) |outgoing_message| { @@ -340,7 +349,7 @@ const stack_frames = switch (zig_builtin.mode) { pub fn main() !void { var gpa_state = std.heap.GeneralPurposeAllocator(.{ .stack_trace_frames = stack_frames }){}; - defer _ = gpa_state.deinit(); + defer std.debug.assert(!gpa_state.deinit()); var tracy_state = if (tracy.enable_allocation) tracy.tracyAllocator(gpa_state.allocator()) else void{}; const inner_allocator: std.mem.Allocator = if (tracy.enable_allocation) tracy_state.allocator() else gpa_state.allocator(); From a6b7a35367bc2b81612d1a96163ff59b26719d0b Mon Sep 17 00:00:00 2001 From: Alex Kladov Date: Tue, 10 Jan 2023 09:40:40 +0000 Subject: [PATCH 13/24] add tests for textDocument/Definition (#900) --- tests/lsp_features/definition.zig | 76 +++++++++++++++++++++++++++++++ tests/tests.zig | 1 + 2 files changed, 77 insertions(+) create mode 100644 tests/lsp_features/definition.zig diff --git a/tests/lsp_features/definition.zig b/tests/lsp_features/definition.zig new file mode 100644 index 0000000..caed193 --- /dev/null +++ b/tests/lsp_features/definition.zig @@ -0,0 +1,76 @@ +const std = @import("std"); +const mem = std.mem; +const zls = @import("zls"); +const builtin = @import("builtin"); + +const helper = @import("../helper.zig"); +const Context = @import("../context.zig").Context; +const ErrorBuilder = @import("../ErrorBuilder.zig"); + +const types = zls.types; +const offsets = zls.offsets; +const requests = zls.requests; + +const allocator: std.mem.Allocator = std.testing.allocator; + +test "definition - smoke" { + try testDefinition( + \\fn main() void { f<>oo(); } + \\fn foo() void {} + ); +} + +test "definition - cursor is at the end of an identifier" { + try testDefinition( + \\fn main() void { foo<>(); } + \\fn foo() void {} + ); +} + +test "definition - cursor is at the start of an identifier" { + testDefinition( + \\fn main() void { <>foo(); } + \\fn foo() void {} + ) catch |err| switch (err) { + error.UnresolvedDefinition => { + // TODO: #891 + }, + else => return err, + }; +} + +fn testDefinition(source: []const u8) !void { + var phr = try helper.collectClearPlaceholders(allocator, source); + defer phr.deinit(allocator); + + var cursor: offsets.Loc = .{ .start = 0, .end = 0 }; + var def_start: offsets.Loc = .{ .start = 0, .end = 0 }; + var def_end: offsets.Loc = .{ .start = 0, .end = 0 }; + for (phr.locations.items(.old)) |loc, i| { + if (mem.eql(u8, source[loc.start..loc.end], "<>")) cursor = phr.locations.items(.new)[i]; + if (mem.eql(u8, source[loc.start..loc.end], "")) def_start = phr.locations.items(.new)[i]; + if (mem.eql(u8, source[loc.start..loc.end], "")) def_end = phr.locations.items(.new)[i]; + } + + const cursor_lsp = offsets.locToRange(phr.new_source, cursor, .@"utf-16").start; + const def_range_lsp = offsets.locToRange(phr.new_source, .{ .start = def_start.end, .end = def_end.start }, .@"utf-16"); + + var ctx = try Context.init(); + defer ctx.deinit(); + + const test_uri: []const u8 = switch (builtin.os.tag) { + .windows => "file:///C:\\test.zig", + else => "file:///test.zig", + }; + + try ctx.requestDidOpen(test_uri, phr.new_source); + + const params = types.TextDocumentPositionParams{ + .textDocument = .{ .uri = test_uri }, + .position = cursor_lsp, + }; + + const response = try ctx.requestGetResponse(?types.Location, "textDocument/definition", params); + const result = response.result orelse return error.UnresolvedDefinition; + try std.testing.expectEqual(def_range_lsp, result.range); +} diff --git a/tests/tests.zig b/tests/tests.zig index d85c824..f9fb035 100644 --- a/tests/tests.zig +++ b/tests/tests.zig @@ -11,6 +11,7 @@ comptime { // LSP features _ = @import("lsp_features/completion.zig"); + _ = @import("lsp_features/definition.zig"); _ = @import("lsp_features/folding_range.zig"); _ = @import("lsp_features/inlay_hints.zig"); _ = @import("lsp_features/references.zig"); From bbbd54498da9163200313f7a704a5df072f2631b Mon Sep 17 00:00:00 2001 From: Techatrix <19954306+Techatrix@users.noreply.github.com> Date: Tue, 10 Jan 2023 12:36:28 +0000 Subject: [PATCH 14/24] check submodules in build.zig (#904) --- build.zig | 41 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/build.zig b/build.zig index 039f5fe..a3e1a12 100644 --- a/build.zig +++ b/build.zig @@ -111,6 +111,12 @@ pub fn build(b: *std.build.Builder) !void { const tres_path = b.option([]const u8, "tres", "Path to tres package (default: " ++ TRES_DEFAULT_PATH ++ ")") orelse TRES_DEFAULT_PATH; exe.addPackage(.{ .name = "tres", .source = .{ .path = tres_path } }); + const check_submodules_step = CheckSubmodulesStep.init(b, &.{ + known_folders_path, + tres_path, + }); + b.getInstallStep().dependOn(&check_submodules_step.step); + if (enable_tracy) { const client_cpp = "src/tracy/TracyClient.cpp"; @@ -136,7 +142,7 @@ pub fn build(b: *std.build.Builder) !void { exe.install(); const gen_exe = b.addExecutable("zls_gen", "src/config_gen/config_gen.zig"); - gen_exe.addPackage(.{ .name = "tres", .source = .{ .path = "src/tres/tres.zig" } }); + gen_exe.addPackage(.{ .name = "tres", .source = .{ .path = tres_path } }); const gen_cmd = gen_exe.run(); gen_cmd.addArgs(&.{ @@ -150,6 +156,7 @@ pub fn build(b: *std.build.Builder) !void { } const gen_step = b.step("gen", "Regenerate config files"); + gen_step.dependOn(&check_submodules_step.step); gen_step.dependOn(&gen_cmd.step); const test_step = b.step("test", "Run all the tests"); @@ -175,3 +182,35 @@ pub fn build(b: *std.build.Builder) !void { tests.setTarget(target); test_step.dependOn(&tests.step); } + +const CheckSubmodulesStep = struct { + step: std.build.Step, + builder: *std.build.Builder, + submodules: []const []const u8, + + pub fn init(builder: *std.build.Builder, submodules: []const []const u8) *CheckSubmodulesStep { + var self = builder.allocator.create(CheckSubmodulesStep) catch unreachable; + self.* = CheckSubmodulesStep{ + .builder = builder, + .step = std.build.Step.init(.custom, "Check Submodules", builder.allocator, make), + .submodules = builder.allocator.dupe([]const u8, submodules) catch unreachable, + }; + return self; + } + + fn make(step: *std.build.Step) anyerror!void { + const self = @fieldParentPtr(CheckSubmodulesStep, "step", step); + for (self.submodules) |path| { + const access = std.fs.accessAbsolute(self.builder.pathFromRoot(path), .{}); + if (access == error.FileNotFound) { + std.debug.print( + \\Did you clone ZLS with `git clone --recurse-submodules https://github.com/zigtools/zls`? + \\If not you can fix this with `git submodule update --init --recursive`. + \\ + \\ + , .{}); + break; + } + } + } +}; From 20d29fd491cd9afe961c2f972ba6340855460435 Mon Sep 17 00:00:00 2001 From: Lee Cannon Date: Tue, 10 Jan 2023 21:52:03 +0000 Subject: [PATCH 15/24] move log overrides into `std_options` (#902) --- src/main.zig | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/src/main.zig b/src/main.zig index 812f40b..8961081 100644 --- a/src/main.zig +++ b/src/main.zig @@ -11,28 +11,30 @@ const debug = @import("debug.zig"); const logger = std.log.scoped(.main); -// Always set this to debug to make std.log call into our handler, then control the runtime -// value in the definition below. -pub const log_level = .debug; - var actual_log_level: std.log.Level = switch (zig_builtin.mode) { .Debug => .debug, else => @intToEnum(std.log.Level, @enumToInt(build_options.log_level)), // temporary fix to build failing on release-safe due to a Zig bug }; -pub fn log( - comptime level: std.log.Level, - comptime scope: @TypeOf(.EnumLiteral), - comptime format: []const u8, - args: anytype, -) void { - if (@enumToInt(level) > @enumToInt(actual_log_level)) return; +pub const std_options = struct { + // Always set this to debug to make std.log call into our handler, then control the runtime + // value in the definition below. + pub const log_level = .debug; - const level_txt = comptime level.asText(); + pub fn logFn( + comptime level: std.log.Level, + comptime scope: @TypeOf(.EnumLiteral), + comptime format: []const u8, + args: anytype, + ) void { + if (@enumToInt(level) > @enumToInt(actual_log_level)) return; - std.debug.print("{s:<5}: ({s:^6}): ", .{ level_txt, @tagName(scope) }); - std.debug.print(format ++ "\n", args); -} + const level_txt = comptime level.asText(); + + std.debug.print("{s:<5}: ({s:^6}): ", .{ level_txt, @tagName(scope) }); + std.debug.print(format ++ "\n", args); + } +}; fn loop( server: *Server, @@ -86,7 +88,7 @@ fn loop( server.processJsonRpc(&arena, json_message); - if(server.status == .exiting_success or server.status == .exiting_failure) return; + if (server.status == .exiting_success or server.status == .exiting_failure) return; } } From 61fa98065fffee306873072733b93840df1dd683 Mon Sep 17 00:00:00 2001 From: Alex Kladov Date: Wed, 11 Jan 2023 20:18:37 +0000 Subject: [PATCH 16/24] fix use after free (#911) --- src/DocumentStore.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DocumentStore.zig b/src/DocumentStore.zig index ec72988..0edaf1a 100644 --- a/src/DocumentStore.zig +++ b/src/DocumentStore.zig @@ -694,7 +694,7 @@ fn createDocument(self: *DocumentStore, uri: Uri, text: [:0]u8, open: bool) erro handle.associated_build_file = gop.key_ptr.*; break; } else if (handle.associated_build_file == null) { - handle.associated_build_file = build_file_uri; + handle.associated_build_file = gop.key_ptr.*; } } } From 8d53a5382d1b01fa68de8d6072b8f74586d86f5e Mon Sep 17 00:00:00 2001 From: Techatrix <19954306+Techatrix@users.noreply.github.com> Date: Mon, 16 Jan 2023 19:46:33 +0100 Subject: [PATCH 17/24] resolve type of `@typeInfo` (#915) --- src/analysis.zig | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/analysis.zig b/src/analysis.zig index 5b3ef86..cf92e92 100644 --- a/src/analysis.zig +++ b/src/analysis.zig @@ -3,6 +3,7 @@ const DocumentStore = @import("DocumentStore.zig"); const Ast = std.zig.Ast; const types = @import("lsp.zig"); const offsets = @import("offsets.zig"); +const URI = @import("uri.zig"); const log = std.log.scoped(.analysis); const ast = @import("ast.zig"); const ComptimeInterpreter = @import("ComptimeInterpreter.zig"); @@ -965,6 +966,30 @@ pub fn resolveTypeOfNodeInternal(store: *DocumentStore, arena: *std.heap.ArenaAl return resolved_type; } + if (std.mem.eql(u8, call_name, "@typeInfo")) { + const zig_lib_path = try URI.fromPath(arena.allocator(), store.config.zig_lib_path orelse return null); + + const builtin_uri = URI.pathRelative(arena.allocator(), zig_lib_path, "/std/builtin.zig") catch |err| switch (err) { + error.OutOfMemory => |e| return e, + else => return null, + }; + + const new_handle = store.getOrLoadHandle(builtin_uri) orelse return null; + const root_scope = new_handle.document_scope.scopes.items[0]; + const decl = root_scope.decls.get("Type") orelse return null; + if (decl != .ast_node) return null; + + const var_decl = ast.varDecl(new_handle.tree, decl.ast_node) orelse return null; + + return TypeWithHandle{ + .type = .{ + .data = .{ .other = var_decl.ast.init_node }, + .is_type_val = false, + }, + .handle = new_handle, + }; + } + if (std.mem.eql(u8, call_name, "@import")) { if (params.len == 0) return null; const import_param = params[0]; From 4e4761b34c90e0361b541d0de3cb05f870fa3be5 Mon Sep 17 00:00:00 2001 From: Techatrix <19954306+Techatrix@users.noreply.github.com> Date: Mon, 16 Jan 2023 19:47:06 +0100 Subject: [PATCH 18/24] fix use after free for builtin completions (#914) --- src/Server.zig | 83 +++++++++++++++++++++++++++++--------------------- 1 file changed, 49 insertions(+), 34 deletions(-) diff --git a/src/Server.zig b/src/Server.zig index 975409b..76652c9 100644 --- a/src/Server.zig +++ b/src/Server.zig @@ -34,7 +34,7 @@ config: *Config, allocator: std.mem.Allocator = undefined, arena: *std.heap.ArenaAllocator = undefined, document_store: DocumentStore = undefined, -builtin_completions: std.ArrayListUnmanaged(types.CompletionItem), +builtin_completions: ?std.ArrayListUnmanaged(types.CompletionItem), client_capabilities: ClientCapabilities = .{}, outgoing_messages: std.ArrayListUnmanaged([]const u8) = .{}, recording_enabled: bool, @@ -1289,6 +1289,49 @@ fn populateSnippedCompletions( } } +fn completeBuiltin(server: *Server) error{OutOfMemory}!?[]types.CompletionItem { + const tracy_zone = tracy.trace(@src()); + defer tracy_zone.end(); + + const allocator = server.arena.allocator(); + + const builtin_completions = if (server.builtin_completions) |completions| + return completions.items + else blk: { + server.builtin_completions = try std.ArrayListUnmanaged(types.CompletionItem).initCapacity(server.allocator, data.builtins.len); + break :blk &server.builtin_completions.?; + }; + + for (data.builtins) |builtin| { + const insert_text = if (server.config.enable_snippets) builtin.snippet else builtin.name; + builtin_completions.appendAssumeCapacity(.{ + .label = builtin.name, + .kind = .Function, + .filterText = builtin.name[1..], + .detail = builtin.signature, + .insertText = if (server.config.include_at_in_builtins) insert_text else insert_text[1..], + .insertTextFormat = if (server.config.enable_snippets) .Snippet else .PlainText, + .documentation = .{ + .MarkupContent = .{ + .kind = .markdown, + .value = builtin.documentation, + }, + }, + }); + } + + var completions = try allocator.alloc(types.CompletionItem, builtin_completions.items.len); + + if (server.client_capabilities.label_details_support) { + for (builtin_completions.items) |item, i| { + completions[i] = item; + try formatDetailledLabel(&completions[i], allocator); + } + } + + return completions; +} + fn completeGlobal(server: *Server, pos_index: usize, handle: *const DocumentStore.Handle) error{OutOfMemory}![]types.CompletionItem { const tracy_zone = tracy.trace(@src()); defer tracy_zone.end(); @@ -1691,14 +1734,6 @@ fn initializeHandler(server: *Server, request: types.InitializeParams) Error!typ } } - // NOTE: everything is initialized, we got the client capabilities - // so we can now format the prebuilt builtins items for labelDetails - if (server.client_capabilities.label_details_support) { - for (server.builtin_completions.items) |*item| { - try formatDetailledLabel(item, server.arena.allocator()); - } - } - if (request.capabilities.workspace) |workspace| { server.client_capabilities.supports_apply_edits = workspace.applyEdit orelse false; server.client_capabilities.supports_configuration = workspace.configuration orelse false; @@ -2067,7 +2102,7 @@ fn completionHandler(server: *Server, request: types.CompletionParams) Error!?ty const pos_context = try analysis.getPositionContext(server.arena.allocator(), handle.text, source_index); const maybe_completions = switch (pos_context) { - .builtin => server.builtin_completions.items, + .builtin => try server.completeBuiltin(), .var_access, .empty => try server.completeGlobal(source_index, handle), .field_access => |loc| try server.completeFieldAccess(handle, source_index, loc), .global_error_set => try server.completeError(handle), @@ -3008,7 +3043,8 @@ fn processMessage(server: *Server, message: Message) Error!void { return error.InvalidRequest; // server received a request after shutdown! }, .exiting_success, - .exiting_failure, => unreachable, + .exiting_failure, + => unreachable, } const start_time = std.time.milliTimestamp(); @@ -3116,32 +3152,11 @@ pub fn init( }; errdefer document_store.deinit(); - var builtin_completions = try std.ArrayListUnmanaged(types.CompletionItem).initCapacity(allocator, data.builtins.len); - errdefer builtin_completions.deinit(allocator); - - for (data.builtins) |builtin| { - const insert_text = if (config.enable_snippets) builtin.snippet else builtin.name; - builtin_completions.appendAssumeCapacity(.{ - .label = builtin.name, - .kind = .Function, - .filterText = builtin.name[1..], - .detail = builtin.signature, - .insertText = if (config.include_at_in_builtins) insert_text else insert_text[1..], - .insertTextFormat = if (config.enable_snippets) .Snippet else .PlainText, - .documentation = .{ - .MarkupContent = .{ - .kind = .markdown, - .value = builtin.documentation, - }, - }, - }); - } - return Server{ .config = config, .allocator = allocator, .document_store = document_store, - .builtin_completions = builtin_completions, + .builtin_completions = null, .recording_enabled = recording_enabled, .replay_enabled = replay_enabled, .status = .uninitialized, @@ -3152,7 +3167,7 @@ pub fn deinit(server: *Server) void { server.document_store.deinit(); analysis.deinit(); - server.builtin_completions.deinit(server.allocator); + if (server.builtin_completions) |*completions| completions.deinit(server.allocator); for (server.outgoing_messages.items) |message| { server.allocator.free(message); From af85a9550d0ff30defd5d8ca6cd36185ccf8bd1b Mon Sep 17 00:00:00 2001 From: Techatrix <19954306+Techatrix@users.noreply.github.com> Date: Mon, 16 Jan 2023 19:47:55 +0100 Subject: [PATCH 19/24] simplify formatting handler (#916) --- src/Server.zig | 23 ++++++----------------- src/diff.zig | 25 ++++++++++++------------- 2 files changed, 18 insertions(+), 30 deletions(-) diff --git a/src/Server.zig b/src/Server.zig index 76652c9..99bc6e5 100644 --- a/src/Server.zig +++ b/src/Server.zig @@ -2263,27 +2263,16 @@ fn formattingHandler(server: *Server, request: types.DocumentFormattingParams) E if (std.mem.eql(u8, handle.text, formatted)) return null; - // avoid computing diffs if the output is small - const maybe_edits = if (formatted.len <= 512) null else diff.edits(allocator, handle.text, formatted) catch null; - - const edits = maybe_edits orelse { - // if edits have been computed we replace the entire file with the formatted text - return &[1]types.TextEdit{.{ + if (formatted.len <= 512) { + var text_edits = try allocator.alloc(types.TextEdit, 1); + text_edits[0] = .{ .range = offsets.locToRange(handle.text, .{ .start = 0, .end = handle.text.len }, server.offset_encoding), .newText = formatted, - }}; - }; - - // Convert from `[]diff.Edit` to `[]types.TextEdit` - var text_edits = try std.ArrayListUnmanaged(types.TextEdit).initCapacity(allocator, edits.items.len); - for (edits.items) |edit| { - text_edits.appendAssumeCapacity(.{ - .range = edit.range, - .newText = edit.newText.items, - }); + }; + return text_edits; } - return text_edits.items; + return if (diff.edits(allocator, handle.text, formatted)) |text_edits| text_edits.items else |_| null; } fn didChangeConfigurationHandler(server: *Server, request: configuration.DidChangeConfigurationParams) Error!void { diff --git a/src/diff.zig b/src/diff.zig index 4c0ad40..49bf4f7 100644 --- a/src/diff.zig +++ b/src/diff.zig @@ -4,13 +4,6 @@ const offsets = @import("offsets.zig"); pub const Error = error{ OutOfMemory, InvalidRange }; -// This is essentially the same as `types.TextEdit`, but we use an -// ArrayList(u8) here to be able to clean up the memory later on -pub const Edit = struct { - range: types.Range, - newText: std.ArrayListUnmanaged(u8), -}; - // Whether the `Change` is an addition, deletion, or no change from the // original string to the new string const Operation = enum { Deletion, Addition, Nothing }; @@ -28,7 +21,7 @@ pub fn edits( allocator: std.mem.Allocator, a: []const u8, b: []const u8, -) Error!std.ArrayListUnmanaged(Edit) { +) Error!std.ArrayListUnmanaged(types.TextEdit) { // Given the input strings A and B, we skip over the first N characters // where A[0..N] == B[0..N]. We want to trim the start (and end) of the // strings that have the same text. This decreases the size of the LCS @@ -186,7 +179,7 @@ pub fn get_changes( a_trim: []const u8, b_trim: []const u8, allocator: std.mem.Allocator, -) Error!std.ArrayListUnmanaged(Edit) { +) Error!std.ArrayListUnmanaged(types.TextEdit) { // First we get a list of changes between strings at the character level: // "addition", "deletion", and "no change" for each character var changes = try std.ArrayListUnmanaged(Change).initCapacity(allocator, a_trim.len); @@ -235,14 +228,20 @@ pub fn get_changes( std.mem.reverse([]Change, groups.items); for (groups.items) |group| std.mem.reverse(Change, group); - var edit_results = std.ArrayListUnmanaged(Edit){}; - errdefer edit_results.deinit(allocator); + var edit_results = try std.ArrayListUnmanaged(types.TextEdit).initCapacity(allocator, groups.items.len); + errdefer { + for (edit_results.items) |edit| { + allocator.free(edit.newText); + } + edit_results.deinit(allocator); + } // Convert our grouped changes into `Edit`s for (groups.items) |group| { var range_start = group[0].pos; var range_len: usize = 0; var newText = std.ArrayListUnmanaged(u8){}; + errdefer newText.deinit(allocator); for (group) |ch| { switch (ch.operation) { .Addition => try newText.append(allocator, ch.value.?), @@ -256,9 +255,9 @@ pub fn get_changes( a_trim_offset + range_start + range_len, ); a_lines.reset(); - try edit_results.append(allocator, Edit{ + edit_results.appendAssumeCapacity(.{ .range = range, - .newText = newText, + .newText = try newText.toOwnedSlice(allocator), }); } From 9e74afada65b521ed9a8d9969623431428822510 Mon Sep 17 00:00:00 2001 From: Techatrix <19954306+Techatrix@users.noreply.github.com> Date: Mon, 16 Jan 2023 19:49:00 +0100 Subject: [PATCH 20/24] show better zig/zls version mismatch messages (#917) * show better zig/zls version mismatch messages * always show message if versions don't match * ignore patch --- src/Server.zig | 36 +++++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/src/Server.zig b/src/Server.zig index 99bc6e5..e3bef95 100644 --- a/src/Server.zig +++ b/src/Server.zig @@ -188,6 +188,12 @@ fn showMessage( args: anytype, ) void { const message = std.fmt.allocPrint(server.arena.allocator(), fmt, args) catch return; + switch (message_type) { + .Error => log.err("{s}", .{message}), + .Warning => log.warn("{s}", .{message}), + .Info => log.info("{s}", .{message}), + .Log => log.debug("{s}", .{message}), + } server.sendNotification("window/showMessage", types.ShowMessageParams{ .type = message_type, .message = message, @@ -1757,12 +1763,32 @@ fn initializeHandler(server: *Server, request: types.InitializeParams) Error!typ const env = configuration.getZigEnv(server.allocator, exe_path) orelse break :blk; defer std.json.parseFree(configuration.Env, env, .{ .allocator = server.allocator }); - const zig_exe_version = std.SemanticVersion.parse(env.version) catch break :blk; + const zig_version = std.SemanticVersion.parse(env.version) catch break :blk; + const zls_version = comptime std.SemanticVersion.parse(build_options.version) catch unreachable; - if (zig_builtin.zig_version.order(zig_exe_version) == .gt) { - server.showMessage(.Warning, - \\ZLS was built with Zig {}, but your Zig version is {s}. Update Zig to avoid unexpected behavior. - , .{ zig_builtin.zig_version, env.version }); + const zig_version_simple = std.SemanticVersion{ + .major = zig_version.major, + .minor = zig_version.minor, + .patch = 0, + }; + const zls_version_simple = std.SemanticVersion{ + .major = zls_version.major, + .minor = zls_version.minor, + .patch = 0, + }; + + switch (zig_version_simple.order(zls_version_simple)) { + .lt => { + server.showMessage(.Warning, + \\Zig `{}` is older than ZLS `{}`. Update Zig to avoid unexpected behavior. + , .{ zig_version, zls_version }); + }, + .eq => {}, + .gt => { + server.showMessage(.Warning, + \\Zig `{}` is newer than ZLS `{}`. Update ZLS to avoid unexpected behavior. + , .{ zig_version, zls_version }); + }, } } else { server.showMessage(.Warning, From 52df02c0f1c7a695537cb2f87f624d84a2c033ea Mon Sep 17 00:00:00 2001 From: Auguste Rame <19855629+SuperAuguste@users.noreply.github.com> Date: Mon, 16 Jan 2023 20:15:12 -0500 Subject: [PATCH 21/24] Add fuzzing on deploy (#918) --- .github/workflows/main.yml | 38 +++++++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 21f7ebd..1bbceff 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -10,6 +10,10 @@ on: schedule: - cron: "0 0 * * *" workflow_dispatch: + inputs: + bypass_tracy_and_artifacts: + type: boolean + description: Bypass Tracy and artifact builds (much faster) jobs: build: @@ -33,14 +37,14 @@ jobs: run: zig build - name: Build with Tracy - if: ${{ matrix.os != 'macos-latest' }} + if: ${{ matrix.os != 'macos-latest' && github.event.inputs.bypass_tracy_and_artifacts == 'false' }} run: zig build -Denable_tracy -Denable_tracy_allocation - name: Run Tests run: zig build test - name: Build artifacts - if: ${{ matrix.os == 'ubuntu-latest' }} + if: ${{ matrix.os == 'ubuntu-latest' && github.event.inputs.bypass_tracy_and_artifacts == 'false' }} run: | declare -a targets=("x86_64-windows" "x86_64-linux" "x86_64-macos" "x86-windows" "x86-linux" "aarch64-linux" "aarch64-macos") mkdir -p "artifacts/" @@ -60,49 +64,49 @@ jobs: done - name: Upload x86_64-windows artifact - if: ${{ matrix.os == 'ubuntu-latest' }} + if: ${{ matrix.os == 'ubuntu-latest' && github.event.inputs.bypass_tracy_and_artifacts == 'false' }} uses: actions/upload-artifact@v3 with: name: zls-x86_64-windows path: artifacts/x86_64-windows/ - name: Upload x86_64-linux artifact - if: ${{ matrix.os == 'ubuntu-latest' }} + if: ${{ matrix.os == 'ubuntu-latest' && github.event.inputs.bypass_tracy_and_artifacts == 'false' }} uses: actions/upload-artifact@v3 with: name: zls-x86_64-linux path: artifacts/x86_64-linux/ - name: Upload x86_64-macos artifact - if: ${{ matrix.os == 'ubuntu-latest' }} + if: ${{ matrix.os == 'ubuntu-latest' && github.event.inputs.bypass_tracy_and_artifacts == 'false' }} uses: actions/upload-artifact@v3 with: name: zls-x86_64-macos path: artifacts/x86_64-macos/ - name: Upload x86-windows artifact - if: ${{ matrix.os == 'ubuntu-latest' }} + if: ${{ matrix.os == 'ubuntu-latest' && github.event.inputs.bypass_tracy_and_artifacts == 'false' }} uses: actions/upload-artifact@v3 with: name: zls-x86-windows path: artifacts/x86-windows/ - name: Upload x86-linux artifact - if: ${{ matrix.os == 'ubuntu-latest' }} + if: ${{ matrix.os == 'ubuntu-latest' && github.event.inputs.bypass_tracy_and_artifacts == 'false' }} uses: actions/upload-artifact@v3 with: name: zls-x86-linux path: artifacts/x86-linux/ - name: Upload aarch64-linux artifact - if: ${{ matrix.os == 'ubuntu-latest' }} + if: ${{ matrix.os == 'ubuntu-latest' && github.event.inputs.bypass_tracy_and_artifacts == 'false' }} uses: actions/upload-artifact@v3 with: name: zls-aarch64-linux path: artifacts/aarch64-linux/ - name: Upload aarch64-macos artifact - if: ${{ matrix.os == 'ubuntu-latest' }} + if: ${{ matrix.os == 'ubuntu-latest' && github.event.inputs.bypass_tracy_and_artifacts == 'false' }} uses: actions/upload-artifact@v3 with: name: zls-aarch64-macos @@ -118,3 +122,19 @@ jobs: REMOTE_HOST: ${{ secrets.WEBSITE_DEPLOY_HOST }} REMOTE_USER: ${{ secrets.WEBSITE_DEPLOY_USER }} TARGET: ${{ secrets.WEBSITE_DEPLOY_FOLDER }} + + - name: Instruct fuzzing server to pull latest zls + if: ${{ matrix.os == 'ubuntu-latest' && github.ref == 'refs/heads/master' && github.repository_owner == 'zigtools' }} + uses: appleboy/ssh-action@v0.1.7 + with: + host: fuzzing.zigtools.org + username: ${{ secrets.FUZZING_SSH_USERNAME }} + key: ${{ secrets.FUZZING_SSH_PRIVKEY }} + script: | + systemctl stop fuzzing + systemctl stop fuzzing-web + cd /root/sus + ./script/setup.sh + systemctl start fuzzing + sleep 5s + systemctl start fuzzing-web From 93abb8cdd560194d25fa63e1fb893e22e763af55 Mon Sep 17 00:00:00 2001 From: Auguste Rame <19855629+SuperAuguste@users.noreply.github.com> Date: Mon, 16 Jan 2023 20:49:28 -0500 Subject: [PATCH 22/24] Fix bypass not having value on PR&commit (#920) --- .github/workflows/main.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 1bbceff..2df721f 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -37,14 +37,14 @@ jobs: run: zig build - name: Build with Tracy - if: ${{ matrix.os != 'macos-latest' && github.event.inputs.bypass_tracy_and_artifacts == 'false' }} + if: ${{ matrix.os != 'macos-latest' && github.event.inputs.bypass_tracy_and_artifacts != 'true' }} run: zig build -Denable_tracy -Denable_tracy_allocation - name: Run Tests run: zig build test - name: Build artifacts - if: ${{ matrix.os == 'ubuntu-latest' && github.event.inputs.bypass_tracy_and_artifacts == 'false' }} + if: ${{ matrix.os == 'ubuntu-latest' && github.event.inputs.bypass_tracy_and_artifacts != 'true' }} run: | declare -a targets=("x86_64-windows" "x86_64-linux" "x86_64-macos" "x86-windows" "x86-linux" "aarch64-linux" "aarch64-macos") mkdir -p "artifacts/" @@ -64,49 +64,49 @@ jobs: done - name: Upload x86_64-windows artifact - if: ${{ matrix.os == 'ubuntu-latest' && github.event.inputs.bypass_tracy_and_artifacts == 'false' }} + if: ${{ matrix.os == 'ubuntu-latest' && github.event.inputs.bypass_tracy_and_artifacts != 'true' }} uses: actions/upload-artifact@v3 with: name: zls-x86_64-windows path: artifacts/x86_64-windows/ - name: Upload x86_64-linux artifact - if: ${{ matrix.os == 'ubuntu-latest' && github.event.inputs.bypass_tracy_and_artifacts == 'false' }} + if: ${{ matrix.os == 'ubuntu-latest' && github.event.inputs.bypass_tracy_and_artifacts != 'true' }} uses: actions/upload-artifact@v3 with: name: zls-x86_64-linux path: artifacts/x86_64-linux/ - name: Upload x86_64-macos artifact - if: ${{ matrix.os == 'ubuntu-latest' && github.event.inputs.bypass_tracy_and_artifacts == 'false' }} + if: ${{ matrix.os == 'ubuntu-latest' && github.event.inputs.bypass_tracy_and_artifacts != 'true' }} uses: actions/upload-artifact@v3 with: name: zls-x86_64-macos path: artifacts/x86_64-macos/ - name: Upload x86-windows artifact - if: ${{ matrix.os == 'ubuntu-latest' && github.event.inputs.bypass_tracy_and_artifacts == 'false' }} + if: ${{ matrix.os == 'ubuntu-latest' && github.event.inputs.bypass_tracy_and_artifacts != 'true' }} uses: actions/upload-artifact@v3 with: name: zls-x86-windows path: artifacts/x86-windows/ - name: Upload x86-linux artifact - if: ${{ matrix.os == 'ubuntu-latest' && github.event.inputs.bypass_tracy_and_artifacts == 'false' }} + if: ${{ matrix.os == 'ubuntu-latest' && github.event.inputs.bypass_tracy_and_artifacts != 'true' }} uses: actions/upload-artifact@v3 with: name: zls-x86-linux path: artifacts/x86-linux/ - name: Upload aarch64-linux artifact - if: ${{ matrix.os == 'ubuntu-latest' && github.event.inputs.bypass_tracy_and_artifacts == 'false' }} + if: ${{ matrix.os == 'ubuntu-latest' && github.event.inputs.bypass_tracy_and_artifacts != 'true' }} uses: actions/upload-artifact@v3 with: name: zls-aarch64-linux path: artifacts/aarch64-linux/ - name: Upload aarch64-macos artifact - if: ${{ matrix.os == 'ubuntu-latest' && github.event.inputs.bypass_tracy_and_artifacts == 'false' }} + if: ${{ matrix.os == 'ubuntu-latest' && github.event.inputs.bypass_tracy_and_artifacts != 'true' }} uses: actions/upload-artifact@v3 with: name: zls-aarch64-macos From 6949989ece0e986b353932a9e987574fc3216bf3 Mon Sep 17 00:00:00 2001 From: Alex Kladov Date: Tue, 17 Jan 2023 17:40:26 +0000 Subject: [PATCH 23/24] Allow setting test filter in `zig build test` (#909) Example usage: $ zig build test -Dtest-filter=definition --- build.zig | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/build.zig b/build.zig index a3e1a12..2dfbd0d 100644 --- a/build.zig +++ b/build.zig @@ -163,6 +163,11 @@ pub fn build(b: *std.build.Builder) !void { test_step.dependOn(b.getInstallStep()); var tests = b.addTest("tests/tests.zig"); + tests.setFilter(b.option( + []const u8, + "test-filter", + "Skip tests that do not match filter", + )); if (coverage) { const src_dir = b.pathJoin(&.{ b.build_root, "src" }); From fa5828496eb8b554ec69ed0beff7a9edcb53411a Mon Sep 17 00:00:00 2001 From: Techatrix <19954306+Techatrix@users.noreply.github.com> Date: Thu, 19 Jan 2023 07:46:42 +0100 Subject: [PATCH 24/24] Generate data files in config_gen.zig (#903) * generate data files in config_gen.zig * remove trailing comma from config.json * update README.md * run zig build gen * handle some unclosed tags * update data file header * generate new data files * remove old data file generators --- README.md | 13 +- build.zig | 12 +- src/Config.zig | 2 +- src/config_gen/config.json | 8 +- src/config_gen/config_gen.zig | 746 ++++++++++++++++++++- src/data/0.10.0.zig | 585 +++++++++++----- src/data/0.7.0.zig | 1175 +++++++++++++++++---------------- src/data/0.7.1.zig | 1175 +++++++++++++++++---------------- src/data/0.8.0.zig | 758 ++++++++++++--------- src/data/0.8.1.zig | 754 ++++++++++++--------- src/data/0.9.0.zig | 606 ++++++++++++----- src/data/0.9.1.zig | 589 ++++++++++++----- src/data/generate-data.js | 107 --- src/data/generate-data.py | 105 --- src/data/master.zig | 529 ++++++++++----- 15 files changed, 4508 insertions(+), 2656 deletions(-) delete mode 100644 src/data/generate-data.js delete mode 100755 src/data/generate-data.py diff --git a/README.md b/README.md index 88e1f06..93ac9da 100644 --- a/README.md +++ b/README.md @@ -44,17 +44,8 @@ zig build -Drelease-safe #### Updating Data Files -There is a `generate-data.py` in the `src/data` folder, run this file to update data files. -It writes to stdout and you can redirect output to a zig file like `master.zig`. By default it generates data file for `master`, but can be configured to generate for a different version by modifying the `zig_version` variable. Files generated by this tool **contains** formatting information. - -On Powershell 5.1 (the default Powershell on Windows 10 & 11), the following will update `master.zig`. -```pwsh -New-Item -Force .\src\data\master.zig -Value ((python .\src\data\generate-data.py) -split "`r?`n" -join "`n") -``` - -This unweidly command is necesary in order to guarantee Unix-style line endings and UTF-8 text encoding. - -There is also a `generate-data.js` in the `src/data` folder, you'll need to run this inside a Chrome DevTools console and copy the output. Files generated by this tool **does not contain** formatting information. +Run `zig build gen -- --generate-version-data master` to update data files. This command will require an internet connection. +You can replace `master` with a specific zig version like `0.10.0`. Which version ZLS uses can be configured by passing the `-Ddata_version` parameter when building ZLS. ### Configuration Options diff --git a/build.zig b/build.zig index 2dfbd0d..e341cbe 100644 --- a/build.zig +++ b/build.zig @@ -146,14 +146,12 @@ pub fn build(b: *std.build.Builder) !void { const gen_cmd = gen_exe.run(); gen_cmd.addArgs(&.{ - b.fmt("{s}/src/Config.zig", .{b.build_root}), - b.fmt("{s}/schema.json", .{b.build_root}), - b.fmt("{s}/README.md", .{b.build_root}), + b.pathJoin(&.{ b.build_root, "src", "Config.zig" }), + b.pathJoin(&.{ b.build_root, "schema.json" }), + b.pathJoin(&.{ b.build_root, "README.md" }), + b.pathJoin(&.{ b.build_root, "src", "data" }), }); - - if (b.option([]const u8, "vscode-config-path", "Output path to vscode-config")) |path| { - gen_cmd.addArg(b.pathFromRoot(path)); - } + if (b.args) |args| gen_cmd.addArgs(args); const gen_step = b.step("gen", "Regenerate config files"); gen_step.dependOn(&check_submodules_step.step); diff --git a/src/Config.zig b/src/Config.zig index a01861c..4e48028 100644 --- a/src/Config.zig +++ b/src/Config.zig @@ -1,7 +1,7 @@ //! DO NOT EDIT //! Configuration options for zls. //! If you want to add a config option edit -//! src/config_gen/config.zig and run `zig build gen` +//! src/config_gen/config.json and run `zig build gen` //! GENERATED BY src/config_gen/config_gen.zig /// Enables snippet completions when the client also supports them diff --git a/src/config_gen/config.json b/src/config_gen/config.json index f032d33..8084ebf 100644 --- a/src/config_gen/config.json +++ b/src/config_gen/config.json @@ -4,7 +4,7 @@ "name": "enable_snippets", "description": "Enables snippet completions when the client also supports them", "type": "bool", - "default": "true", + "default": "true" }, { "name": "enable_ast_check_diagnostics", @@ -16,13 +16,13 @@ "name": "enable_autofix", "description": "Whether to automatically fix errors on save. Currently supports adding and removing discards.", "type": "bool", - "default": "true", + "default": "true" }, { "name": "enable_import_embedfile_argument_completions", "description": "Whether to enable import/embedFile argument completions", "type": "bool", - "default": "true", + "default": "true" }, { "name": "enable_semantic_tokens", @@ -34,7 +34,7 @@ "name": "enable_inlay_hints", "description": "Enables inlay hint support when the client also supports it", "type": "bool", - "default": "true", + "default": "true" }, { "name": "inlay_hints_show_builtin", diff --git a/src/config_gen/config_gen.zig b/src/config_gen/config_gen.zig index 8939274..0c2de59 100644 --- a/src/config_gen/config_gen.zig +++ b/src/config_gen/config_gen.zig @@ -1,5 +1,6 @@ const std = @import("std"); -const builtin = @import("builtin"); +const zig_builtin = @import("builtin"); + const tres = @import("tres"); const ConfigOption = struct { @@ -54,7 +55,7 @@ fn generateConfigFile(allocator: std.mem.Allocator, config: Config, path: []cons \\//! DO NOT EDIT \\//! Configuration options for zls. \\//! If you want to add a config option edit - \\//! src/config_gen/config.zig and run `zig build gen` + \\//! src/config_gen/config.json and run `zig build gen` \\//! GENERATED BY src/config_gen/config_gen.zig \\ ); @@ -229,18 +230,728 @@ fn generateVSCodeConfigFile(allocator: std.mem.Allocator, config: Config, path: try buffered_writer.flush(); } +/// Tokenizer for a langref.html.in file +/// example file: https://raw.githubusercontent.com/ziglang/zig/master/doc/langref.html.in +/// this is a modified version from https://github.com/ziglang/zig/blob/master/doc/docgen.zig +const Tokenizer = struct { + buffer: []const u8, + index: usize = 0, + state: State = .Start, + + const State = enum { + Start, + LBracket, + Hash, + TagName, + Eof, + }; + + const Token = struct { + id: Id, + start: usize, + end: usize, + + const Id = enum { + Invalid, + Content, + BracketOpen, + TagContent, + Separator, + BracketClose, + Eof, + }; + }; + + fn next(self: *Tokenizer) Token { + var result = Token{ + .id = .Eof, + .start = self.index, + .end = undefined, + }; + while (self.index < self.buffer.len) : (self.index += 1) { + const c = self.buffer[self.index]; + switch (self.state) { + .Start => switch (c) { + '{' => { + self.state = .LBracket; + }, + else => { + result.id = .Content; + }, + }, + .LBracket => switch (c) { + '#' => { + if (result.id != .Eof) { + self.index -= 1; + self.state = .Start; + break; + } else { + result.id = .BracketOpen; + self.index += 1; + self.state = .TagName; + break; + } + }, + else => { + result.id = .Content; + self.state = .Start; + }, + }, + .TagName => switch (c) { + '|' => { + if (result.id != .Eof) { + break; + } else { + result.id = .Separator; + self.index += 1; + break; + } + }, + '#' => { + self.state = .Hash; + }, + else => { + result.id = .TagContent; + }, + }, + .Hash => switch (c) { + '}' => { + if (result.id != .Eof) { + self.index -= 1; + self.state = .TagName; + break; + } else { + result.id = .BracketClose; + self.index += 1; + self.state = .Start; + break; + } + }, + else => { + result.id = .TagContent; + self.state = .TagName; + }, + }, + .Eof => unreachable, + } + } else { + switch (self.state) { + .Start, + .LBracket, + .Eof, + => {}, + else => { + result.id = .Invalid; + }, + } + self.state = .Eof; + } + result.end = self.index; + return result; + } +}; + +const Builtin = struct { + name: []const u8, + signature: []const u8, + documentation: std.ArrayListUnmanaged(u8), +}; + +/// parses a `langref.html.in` file and extracts builtins from this section: `https://ziglang.org/documentation/master/#Builtin-Functions` +/// the documentation field contains poorly formated html +fn collectBuiltinData(allocator: std.mem.Allocator, version: []const u8, langref_file: []const u8) error{OutOfMemory}![]Builtin { + var tokenizer = Tokenizer{ .buffer = langref_file }; + + const State = enum { + /// searching for this line: + /// {#header_open|Builtin Functions|2col#} + searching, + /// skippig builtin functions description: + /// Builtin functions are provided by the compiler and are prefixed ... + prefix, + /// every entry begins with this: + /// {#syntax#}@addrSpaceCast(comptime addrspace: std.builtin.AddressSpace, ptr: anytype) anytype{#endsyntax#} + builtin_begin, + /// iterate over documentation + builtin_content, + }; + var state: State = .searching; + + var builtins = std.ArrayListUnmanaged(Builtin){}; + errdefer { + for (builtins.items) |*builtin| { + builtin.documentation.deinit(allocator); + } + builtins.deinit(allocator); + } + + var depth: u32 = undefined; + while (true) { + const token = tokenizer.next(); + switch (token.id) { + .Content => { + switch (state) { + .builtin_content => { + try builtins.items[builtins.items.len - 1].documentation.appendSlice(allocator, tokenizer.buffer[token.start..token.end]); + }, + else => continue, + } + }, + .BracketOpen => { + const tag_token = tokenizer.next(); + std.debug.assert(tag_token.id == .TagContent); + const tag_name = tokenizer.buffer[tag_token.start..tag_token.end]; + + if (std.mem.eql(u8, tag_name, "header_open")) { + std.debug.assert(tokenizer.next().id == .Separator); + const content_token = tokenizer.next(); + std.debug.assert(tag_token.id == .TagContent); + const content_name = tokenizer.buffer[content_token.start..content_token.end]; + + switch (state) { + .searching => { + if (std.mem.eql(u8, content_name, "Builtin Functions")) { + state = .prefix; + depth = 0; + } + }, + .prefix, .builtin_begin => { + state = .builtin_begin; + try builtins.append(allocator, .{ + .name = content_name, + .signature = "", + .documentation = .{}, + }); + }, + .builtin_content => unreachable, + } + if (state != .searching) { + depth += 1; + } + + while (true) { + const bracket_tok = tokenizer.next(); + switch (bracket_tok.id) { + .BracketClose => break, + .Separator, .TagContent => continue, + else => unreachable, + } + } + } else if (std.mem.eql(u8, tag_name, "header_close")) { + std.debug.assert(tokenizer.next().id == .BracketClose); + + if (state == .builtin_content) { + state = .builtin_begin; + } + if (state != .searching) { + depth -= 1; + if (depth == 0) break; + } + } else if (state != .searching and std.mem.eql(u8, tag_name, "syntax")) { + std.debug.assert(tokenizer.next().id == .BracketClose); + const content_tag = tokenizer.next(); + std.debug.assert(content_tag.id == .Content); + const content_name = tokenizer.buffer[content_tag.start..content_tag.end]; + std.debug.assert(tokenizer.next().id == .BracketOpen); + const end_syntax_tag = tokenizer.next(); + std.debug.assert(end_syntax_tag.id == .TagContent); + const end_tag_name = tokenizer.buffer[end_syntax_tag.start..end_syntax_tag.end]; + std.debug.assert(std.mem.eql(u8, end_tag_name, "endsyntax")); + std.debug.assert(tokenizer.next().id == .BracketClose); + + switch (state) { + .builtin_begin => { + builtins.items[builtins.items.len - 1].signature = content_name; + state = .builtin_content; + }, + .builtin_content => { + const writer = builtins.items[builtins.items.len - 1].documentation.writer(allocator); + + try writeMarkdownCode(content_name, "zig", writer); + }, + else => {}, + } + } else if (state != .searching and std.mem.eql(u8, tag_name, "syntax_block")) { + std.debug.assert(tokenizer.next().id == .Separator); + + const source_type_tag = tokenizer.next(); + std.debug.assert(tag_token.id == .TagContent); + const source_type = tokenizer.buffer[source_type_tag.start..source_type_tag.end]; + switch (tokenizer.next().id) { + .Separator => { + std.debug.assert(tokenizer.next().id == .TagContent); + std.debug.assert(tokenizer.next().id == .BracketClose); + }, + .BracketClose => {}, + else => unreachable, + } + + var content_token = tokenizer.next(); + std.debug.assert(content_token.id == .Content); + const content = tokenizer.buffer[content_token.start..content_token.end]; + const writer = builtins.items[builtins.items.len - 1].documentation.writer(allocator); + try writeMarkdownCode(content, source_type, writer); + + std.debug.assert(tokenizer.next().id == .BracketOpen); + const end_code_token = tokenizer.next(); + std.debug.assert(tag_token.id == .TagContent); + const end_code_name = tokenizer.buffer[end_code_token.start..end_code_token.end]; + std.debug.assert(std.mem.eql(u8, end_code_name, "end_syntax_block")); + std.debug.assert(tokenizer.next().id == .BracketClose); + } else if (state != .searching and std.mem.eql(u8, tag_name, "link")) { + std.debug.assert(tokenizer.next().id == .Separator); + const name_token = tokenizer.next(); + std.debug.assert(name_token.id == .TagContent); + const name = tokenizer.buffer[name_token.start..name_token.end]; + + const url_name = switch (tokenizer.next().id) { + .Separator => blk: { + const url_name_token = tokenizer.next(); + std.debug.assert(url_name_token.id == .TagContent); + const url_name = tokenizer.buffer[url_name_token.start..url_name_token.end]; + std.debug.assert(tokenizer.next().id == .BracketClose); + break :blk url_name; + }, + .BracketClose => name, + else => unreachable, + }; + + const spaceless_url_name = try std.mem.replaceOwned(u8, allocator, url_name, " ", "-"); + defer allocator.free(spaceless_url_name); + + const writer = builtins.items[builtins.items.len - 1].documentation.writer(allocator); + try writer.print("[{s}](https://ziglang.org/documentation/{s}/#{s})", .{ + name, + version, + std.mem.trimLeft(u8, spaceless_url_name, "@"), + }); + } else if (state != .searching and std.mem.eql(u8, tag_name, "code_begin")) { + std.debug.assert(tokenizer.next().id == .Separator); + std.debug.assert(tokenizer.next().id == .TagContent); + switch (tokenizer.next().id) { + .Separator => { + std.debug.assert(tokenizer.next().id == .TagContent); + std.debug.assert(tokenizer.next().id == .BracketClose); + }, + .BracketClose => {}, + else => unreachable, + } + + while (true) { + const content_token = tokenizer.next(); + std.debug.assert(content_token.id == .Content); + const content = tokenizer.buffer[content_token.start..content_token.end]; + std.debug.assert(tokenizer.next().id == .BracketOpen); + const end_code_token = tokenizer.next(); + std.debug.assert(end_code_token.id == .TagContent); + const end_tag_name = tokenizer.buffer[end_code_token.start..end_code_token.end]; + + if (std.mem.eql(u8, end_tag_name, "code_end")) { + std.debug.assert(tokenizer.next().id == .BracketClose); + + const writer = builtins.items[builtins.items.len - 1].documentation.writer(allocator); + try writeMarkdownCode(content, "zig", writer); + break; + } + std.debug.assert(tokenizer.next().id == .BracketClose); + } + } else { + while (true) { + switch (tokenizer.next().id) { + .Eof => unreachable, + .BracketClose => break, + else => continue, + } + } + } + }, + else => unreachable, + } + } + + return try builtins.toOwnedSlice(allocator); +} + +/// single line: \`{content}\` +/// multi line: +/// \`\`\`{source_type} +/// {content} +/// \`\`\` +fn writeMarkdownCode(content: []const u8, source_type: []const u8, writer: anytype) @TypeOf(writer).Error!void { + const trimmed_content = std.mem.trim(u8, content, " \n"); + const is_multiline = std.mem.indexOfScalar(u8, trimmed_content, '\n') != null; + if (is_multiline) { + var line_it = std.mem.tokenize(u8, trimmed_content, "\n"); + try writer.print("\n```{s}", .{source_type}); + while (line_it.next()) |line| { + try writer.print("\n{s}", .{line}); + } + try writer.writeAll("\n```"); + } else { + try writer.print("`{s}`", .{trimmed_content}); + } +} + +fn writeLine(str: []const u8, single_line: bool, writer: anytype) @TypeOf(writer).Error!void { + const trimmed_content = std.mem.trim(u8, str, &std.ascii.whitespace); + if (trimmed_content.len == 0) return; + + if (single_line) { + var line_it = std.mem.split(u8, trimmed_content, "\n"); + while (line_it.next()) |line| { + try writer.print("{s} ", .{std.mem.trim(u8, line, &std.ascii.whitespace)}); + } + } else { + try writer.writeAll(trimmed_content); + } + + try writer.writeByte('\n'); +} + +/// converts text with various html tags into markdown +/// supported tags: +/// - `

` +/// - `

`
+/// - ``
+/// - `", "", "", "" };
+        const tag_index = for (tags) |tag_name, i| {
+            if (std.mem.startsWith(u8, html[tag_start_index + 1 ..], tag_name)) break i;
+        } else {
+            index += 1;
+            continue;
+        };
+
+        try writeLine(html[index..tag_start_index], single_line, writer);
+
+        const tag_name = tags[tag_index];
+        const opening_tag_name = opening_tags[tag_index];
+        const closing_tag_name = closing_tags[tag_index];
+
+        // std.debug.print("tag: '{s}'\n", .{tag_name});
+
+        const content_start = 1 + (std.mem.indexOfScalarPos(u8, html, tag_start_index + 1 + tag_name.len, '>') orelse return error.InvalidTag);
+
+        index = content_start;
+        const content_end = while (std.mem.indexOfScalarPos(u8, html, index, '<')) |end| {
+            if (std.mem.startsWith(u8, html[end..], closing_tag_name)) break end;
+            if (std.mem.startsWith(u8, html[end..], opening_tag_name)) {
+                index = std.mem.indexOfPos(u8, html, end + opening_tag_name.len, closing_tag_name) orelse return error.MissingEndTag;
+                index += closing_tag_name.len;
+                continue;
+            }
+            index += 1;
+        } else html.len;
+
+        const content = html[content_start..content_end];
+        index = @min(html.len, content_end + closing_tag_name.len);
+        // std.debug.print("content: {s}\n", .{content});
+
+        if (std.mem.eql(u8, tag_name, "p")) {
+            try writeMarkdownFromHtmlInternal(content, true, depth, writer);
+            try writer.writeByte('\n');
+        } else if (std.mem.eql(u8, tag_name, "pre")) {
+            try writeMarkdownFromHtmlInternal(content, false, depth, writer);
+        } else if (std.mem.eql(u8, tag_name, "em")) {
+            try writer.print("**{s}** ", .{content});
+        } else if (std.mem.eql(u8, tag_name, "ul")) {
+            try writeMarkdownFromHtmlInternal(content, false, depth + 1, writer);
+        } else if (std.mem.eql(u8, tag_name, "li")) {
+            try writer.writeByteNTimes(' ', 1 + (depth -| 1) * 2);
+            try writer.writeAll("- ");
+            try writeMarkdownFromHtmlInternal(content, true, depth, writer);
+        } else if (std.mem.eql(u8, tag_name, "a")) {
+            const href_part = std.mem.trimLeft(u8, html[tag_start_index + 2 .. content_start - 1], " ");
+            std.debug.assert(std.mem.startsWith(u8, href_part, "href=\""));
+            std.debug.assert(href_part[href_part.len - 1] == '\"');
+            const url = href_part["href=\"".len .. href_part.len - 1];
+            try writer.print("[{s}]({s})", .{ content, std.mem.trimLeft(u8, url, "@") });
+        } else if (std.mem.eql(u8, tag_name, "code")) {
+            try writeMarkdownCode(content, "zig", writer);
+        } else return error.UnsupportedTag;
+    }
+
+    try writeLine(html[index..], single_line, writer);
+}
+
+/// takes in a signature like this: `@intToEnum(comptime DestType: type, integer: anytype) DestType`
+/// and outputs its arguments: `comptime DestType: type`, `integer: anytype`
+fn extractArgumentsFromSignature(allocator: std.mem.Allocator, signature: []const u8) error{OutOfMemory}![][]const u8 {
+    var arguments = std.ArrayListUnmanaged([]const u8){};
+    defer arguments.deinit(allocator);
+
+    var argument_start: usize = 0;
+    var index: usize = 0;
+    while (std.mem.indexOfAnyPos(u8, signature, index, ",()")) |token_index| {
+        if (signature[token_index] == '(') {
+            argument_start = index;
+            index = 1 + std.mem.indexOfScalarPos(u8, signature, token_index + 1, ')').?;
+            continue;
+        }
+        const argument = std.mem.trim(u8, signature[argument_start..token_index], &std.ascii.whitespace);
+        if (argument.len != 0) try arguments.append(allocator, argument);
+        if (signature[token_index] == ')') break;
+        argument_start = token_index + 1;
+        index = token_index + 1;
+    }
+
+    return arguments.toOwnedSlice(allocator);
+}
+
+/// takes in a signature like this: `@intToEnum(comptime DestType: type, integer: anytype) DestType`
+/// and outputs a snippet: `@intToEnum(${1:comptime DestType: type}, ${2:integer: anytype})`
+fn extractSnippetFromSignature(allocator: std.mem.Allocator, signature: []const u8) error{OutOfMemory}![]const u8 {
+    var snippet = std.ArrayListUnmanaged(u8){};
+    defer snippet.deinit(allocator);
+    var writer = snippet.writer(allocator);
+
+    const start_index = 1 + std.mem.indexOfScalar(u8, signature, '(').?;
+    try writer.writeAll(signature[0..start_index]);
+
+    var argument_start: usize = start_index;
+    var index: usize = start_index;
+    var i: u32 = 1;
+    while (std.mem.indexOfAnyPos(u8, signature, index, ",()")) |token_index| {
+        if (signature[token_index] == '(') {
+            argument_start = index;
+            index = 1 + std.mem.indexOfScalarPos(u8, signature, token_index + 1, ')').?;
+            continue;
+        }
+        const argument = std.mem.trim(u8, signature[argument_start..token_index], &std.ascii.whitespace);
+        if (argument.len != 0) {
+            if (i != 1) try writer.writeAll(", ");
+            try writer.print("${{{d}:{s}}}", .{ i, argument });
+        }
+        if (signature[token_index] == ')') break;
+        argument_start = token_index + 1;
+        index = token_index + 1;
+        i += 1;
+    }
+    try writer.writeByte(')');
+
+    return snippet.toOwnedSlice(allocator);
+}
+
+/// Generates data files from the Zig language Reference (https://ziglang.org/documentation/master/)
+/// An output example would `zls/src/master.zig`
+fn generateVersionDataFile(allocator: std.mem.Allocator, version: []const u8, path: []const u8) !void {
+    const url = try std.fmt.allocPrint(allocator, "https://raw.githubusercontent.com/ziglang/zig/{s}/doc/langref.html.in", .{version});
+    defer allocator.free(url);
+
+    const response = try httpGET(allocator, try std.Uri.parse(url));
+    switch (response) {
+        .ok => {},
+        .other => |status| {
+            const error_name = status.phrase() orelse @tagName(status.class());
+            std.log.err("failed to download {s}: {s}", .{ url, error_name });
+            return error.DownloadFailed;
+        },
+    }
+    defer allocator.free(response.ok);
+
+    const response_bytes = response.ok;
+    // const response_bytes: []const u8 = @embedFile("langref.html.in");
+
+    var builtins = try collectBuiltinData(allocator, version, response_bytes);
+    defer {
+        for (builtins) |*builtin| {
+            builtin.documentation.deinit(allocator);
+        }
+        allocator.free(builtins);
+    }
+
+    var builtin_file = try std.fs.createFileAbsolute(path, .{});
+    defer builtin_file.close();
+
+    var buffered_writer = std.io.bufferedWriter(builtin_file.writer());
+    var writer = buffered_writer.writer();
+
+    try writer.print(
+        \\//! DO NOT EDIT
+        \\//! If you want to update this file run:
+        \\//! `zig build gen -- --generate-version-data {s}` (requires an internet connection)
+        \\//! GENERATED BY src/config_gen/config_gen.zig
+        \\
+        \\const Builtin = struct {{
+        \\    name: []const u8,
+        \\    signature: []const u8,
+        \\    snippet: []const u8,
+        \\    documentation: []const u8,
+        \\    arguments: []const []const u8,
+        \\}};
+        \\
+        \\pub const builtins = [_]Builtin{{
+        \\
+    , .{version});
+
+    for (builtins) |builtin| {
+        const signature = try std.mem.replaceOwned(u8, allocator, builtin.signature, "\n", "");
+        defer allocator.free(signature);
+
+        const snippet = try extractSnippetFromSignature(allocator, signature);
+        defer allocator.free(snippet);
+
+        var arguments = try extractArgumentsFromSignature(allocator, signature[builtin.name.len + 1 ..]);
+        defer allocator.free(arguments);
+
+        try writer.print(
+            \\    .{{
+            \\        .name = "{}",
+            \\        .signature = "{}",
+            \\        .snippet = "{}",
+            \\
+        , .{
+            std.zig.fmtEscapes(builtin.name),
+            std.zig.fmtEscapes(signature),
+            std.zig.fmtEscapes(snippet),
+        });
+
+        const html = builtin.documentation.items["
".len..]; + var markdown = std.ArrayListUnmanaged(u8){}; + defer markdown.deinit(allocator); + try writeMarkdownFromHtml(html, markdown.writer(allocator)); + + try writer.writeAll(" .documentation =\n"); + var line_it = std.mem.split(u8, std.mem.trim(u8, markdown.items, "\n"), "\n"); + while (line_it.next()) |line| { + try writer.print(" \\\\{s}\n", .{std.mem.trimRight(u8, line, " ")}); + } + + try writer.writeAll( + \\ , + \\ .arguments = &.{ + ); + + if (arguments.len != 0) { + try writer.writeByte('\n'); + for (arguments) |arg| { + try writer.print(" \"{}\",\n", .{std.zig.fmtEscapes(arg)}); + } + try writer.writeByteNTimes(' ', 8); + } + + try writer.writeAll( + \\}, + \\ }, + \\ + ); + } + + try writer.writeAll( + \\}; + \\ + \\// DO NOT EDIT + \\ + ); + try buffered_writer.flush(); +} + +const Response = union(enum) { + ok: []const u8, + other: std.http.Status, +}; + +fn httpGET(allocator: std.mem.Allocator, uri: std.Uri) !Response { + var client = std.http.Client{ .allocator = allocator }; + defer client.deinit(allocator); + try client.ca_bundle.rescan(allocator); + + var request = try client.request(uri, .{}, .{}); + defer request.deinit(); + + var output = std.ArrayListUnmanaged(u8){}; + defer output.deinit(allocator); + + var buffer: [1024]u8 = undefined; + while (true) { + const size = try request.read(&buffer); + if (size == 0) break; + try output.appendSlice(allocator, buffer[0..size]); + } + + if (request.response.headers.status != .ok) { + return .{ + .other = request.response.headers.status, + }; + } + + return .{ .ok = try output.toOwnedSlice(allocator) }; +} + pub fn main() !void { var general_purpose_allocator = std.heap.GeneralPurposeAllocator(.{}){}; + defer std.debug.assert(!general_purpose_allocator.deinit()); var gpa = general_purpose_allocator.allocator(); - var arg_it = try std.process.argsWithAllocator(gpa); - defer arg_it.deinit(); + var stderr = std.io.getStdErr().writer(); - _ = arg_it.next() orelse @panic(""); - const config_path = arg_it.next() orelse @panic("first argument must be path to Config.zig"); - const schema_path = arg_it.next() orelse @panic("second argument must be path to schema.json"); - const readme_path = arg_it.next() orelse @panic("third argument must be path to README.md"); - const maybe_vscode_config_path = arg_it.next(); + var args_it = try std.process.argsWithAllocator(gpa); + defer args_it.deinit(); + + _ = args_it.next() orelse @panic(""); + const config_path = args_it.next() orelse @panic("first argument must be path to Config.zig"); + const schema_path = args_it.next() orelse @panic("second argument must be path to schema.json"); + const readme_path = args_it.next() orelse @panic("third argument must be path to README.md"); + const data_path = args_it.next() orelse @panic("fourth argument must be path to data directory"); + + var maybe_vscode_config_path: ?[]const u8 = null; + var maybe_data_file_version: ?[]const u8 = null; + var maybe_data_file_path: ?[]const u8 = null; + + while (args_it.next()) |argname| { + if (std.mem.eql(u8, argname, "--help")) { + try stderr.writeAll( + \\ Usage: zig build gen -- [command] + \\ + \\ Commands: + \\ + \\ --help Prints this message + \\ --vscode-config-path [path] Output zls-vscode configurations + \\ --generate-version-data [version] Output version data file (see src/data/master.zig) + \\ --generate-version-data-path [path] Override default data file path (default: src/data/*.zig) + \\ + ); + } else if (std.mem.eql(u8, argname, "--vscode-config-path")) { + maybe_vscode_config_path = args_it.next() orelse { + try stderr.print("Expected output path after --vscode-config-path argument.\n", .{}); + return; + }; + } else if (std.mem.eql(u8, argname, "--generate-version-data")) { + maybe_data_file_version = args_it.next() orelse { + try stderr.print("Expected version after --generate-version-data argument.\n", .{}); + return; + }; + const is_valid_version = blk: { + if (std.mem.eql(u8, maybe_data_file_version.?, "master")) break :blk true; + _ = std.SemanticVersion.parse(maybe_data_file_version.?) catch break :blk false; + break :blk true; + }; + if (!is_valid_version) { + try stderr.print("'{s}' is not a valid argument after --generate-version-data.\n", .{maybe_data_file_version.?}); + return; + } + } else if (std.mem.eql(u8, argname, "--generate-version-data-path")) { + maybe_data_file_path = args_it.next() orelse { + try stderr.print("Expected output path after --generate-version-data-path argument.\n", .{}); + return; + }; + } else { + try stderr.print("Unrecognized argument '{s}'.\n", .{argname}); + return; + } + } const parse_options = std.json.ParseOptions{ .allocator = gpa, @@ -257,13 +968,22 @@ pub fn main() !void { try generateVSCodeConfigFile(gpa, config, vscode_config_path); } - if (builtin.os.tag == .windows) { + if (maybe_data_file_version) |data_version| { + const path = if (maybe_data_file_path) |path| path else blk: { + const file_name = try std.fmt.allocPrint(gpa, "{s}.zig", .{data_version}); + defer gpa.free(file_name); + break :blk try std.fs.path.join(gpa, &.{ data_path, file_name }); + }; + defer if (maybe_data_file_path == null) gpa.free(path); + + try generateVersionDataFile(gpa, data_version, path); + } + + if (zig_builtin.os.tag == .windows) { std.log.warn("Running on windows may result in CRLF and LF mismatch", .{}); } - try std.io.getStdOut().writeAll( - \\If you have added a new configuration option and it should be configuration through the config wizard, then edit `src/setup.zig` - \\ + try stderr.writeAll( \\Changing configuration options may also require editing the `package.json` from zls-vscode at https://github.com/zigtools/zls-vscode/blob/master/package.json \\You can use `zig build gen -Dvscode-config-path=/path/to/output/file.json` to generate the new configuration properties which you can then copy into `package.json` \\ diff --git a/src/data/0.10.0.zig b/src/data/0.10.0.zig index 82f7a25..275ac04 100644 --- a/src/data/0.10.0.zig +++ b/src/data/0.10.0.zig @@ -1,3 +1,8 @@ +//! DO NOT EDIT +//! If you want to update this file run: +//! `zig build gen -- --generate-version-data 0.10.0` (requires an internet connection) +//! GENERATED BY src/config_gen/config_gen.zig + const Builtin = struct { name: []const u8, signature: []const u8, @@ -60,8 +65,7 @@ pub const builtins = [_]Builtin{ \\ assert(*u32 == *align(@alignOf(u32)) u32); \\} \\``` - \\ - \\The result is a target-specific compile time constant. It is guaranteed to be less than or equal to [@sizeOf(T)](https://ziglang.org/documentation/0.10.0/#@sizeOf). + \\The result is a target-specific compile time constant. It is guaranteed to be less than or equal to [@sizeOf(T)](https://ziglang.org/documentation/0.10.0/#sizeOf). , .arguments = &.{ "comptime T: type", @@ -82,19 +86,38 @@ pub const builtins = [_]Builtin{ .{ .name = "@asyncCall", .signature = "@asyncCall(frame_buffer: []align(@alignOf(@Frame(anyAsyncFunction))) u8, result_ptr, function_ptr, args: anytype) anyframe->T", - .snippet = "@asyncCall(${1:frame_buffer: []align(@alignOf(@Frame(anyAsyncFunction))) u8}, ${2:result_ptr}, ${3:function_ptr}, ${4:args: anytype})", + .snippet = "@asyncCall(${1:frame_buffer: []align(@alignOf(@Frame(anyAsyncFunction)})", .documentation = \\`@asyncCall` performs an `async` call on a function pointer, which may or may not be an [async function](https://ziglang.org/documentation/0.10.0/#Async-Functions). \\ \\The provided `frame_buffer` must be large enough to fit the entire function frame. This size can be determined with [@frameSize](https://ziglang.org/documentation/0.10.0/#frameSize). To provide a too-small buffer invokes safety-checked [Undefined Behavior](https://ziglang.org/documentation/0.10.0/#Undefined-Behavior). \\ - \\`result_ptr` is optional ([null](https://ziglang.org/documentation/0.10.0/#null) may be provided). If provided, the function call will write its result directly to the result pointer, which will be available to read after [await](https://ziglang.org/documentation/0.10.0/#Async-and-Await) completes. Any result location provided to `await` will copy the result from `result_ptr`.

{#code_begin|test|async_struct_field_fn_pointer#} {#backend_stage1#} const std = @import("std"); const expect = std.testing.expect; test "async fn pointer in a struct field" { var data: i32 = 1; const Foo = struct { bar: fn (*i32) callconv(.Async) void, }; var foo = Foo{ .bar = func }; var bytes: [64]u8 align(@alignOf(@Frame(func))) = undefined; const f = @asyncCall(&bytes, {}, foo.bar, .{&data}); try expect(data == 2); resume f; try expect(data == 4); } fn func(y: *i32) void { defer y.* += 2; y.* += 1; suspend {} }` + \\`result_ptr` is optional ([null](https://ziglang.org/documentation/0.10.0/#null) may be provided). If provided, the function call will write its result directly to the result pointer, which will be available to read after [await](https://ziglang.org/documentation/0.10.0/#Async-and-Await) completes. Any result location provided to `await` will copy the result from `result_ptr`. + \\ + \\```zig + \\const std = @import("std"); + \\const expect = std.testing.expect; + \\test "async fn pointer in a struct field" { + \\ var data: i32 = 1; + \\ const Foo = struct { + \\ bar: fn (*i32) callconv(.Async) void, + \\ }; + \\ var foo = Foo{ .bar = func }; + \\ var bytes: [64]u8 align(@alignOf(@Frame(func))) = undefined; + \\ const f = @asyncCall(&bytes, {}, foo.bar, .{&data}); + \\ try expect(data == 2); + \\ resume f; + \\ try expect(data == 4); + \\} + \\fn func(y: *i32) void { + \\ defer y.* += 2; + \\ y.* += 1; + \\ suspend {} + \\} + \\``` , .arguments = &.{ - "frame_buffer: []align(@alignOf(@Frame(anyAsyncFunction))) u8", - "result_ptr", - "function_ptr", - "args: anytype", + "frame_buffer: []align(@alignOf(@Frame(anyAsyncFunction)", }, }, .{ @@ -122,15 +145,16 @@ pub const builtins = [_]Builtin{ \\`T` must be a pointer, a `bool`, a float, an integer or an enum. \\ \\Supported operations: - \\ - `.Xchg` - stores the operand unmodified. Supports enums, integers and floats. - \\ - `.Add` - for integers, twos complement wraparound addition. Also supports [Floats](https://ziglang.org/documentation/0.10.0/#Floats). - \\ - `.Sub` - for integers, twos complement wraparound subtraction. Also supports [Floats](https://ziglang.org/documentation/0.10.0/#Floats). - \\ - `.And` - bitwise and - \\ - `.Nand` - bitwise nand - \\ - `.Or` - bitwise or - \\ - `.Xor` - bitwise xor - \\ - `.Max` - stores the operand if it is larger. Supports integers and floats. - \\ - `.Min` - stores the operand if it is smaller. Supports integers and floats. + \\ + \\ - `.Xchg` - stores the operand unmodified. Supports enums, integers and floats. + \\ - `.Add` - for integers, twos complement wraparound addition. Also supports [Floats](https://ziglang.org/documentation/0.10.0/#Floats). + \\ - `.Sub` - for integers, twos complement wraparound subtraction. Also supports [Floats](https://ziglang.org/documentation/0.10.0/#Floats). + \\ - `.And` - bitwise and + \\ - `.Nand` - bitwise nand + \\ - `.Or` - bitwise or + \\ - `.Xor` - bitwise xor + \\ - `.Max` - stores the operand if it is larger. Supports integers and floats. + \\ - `.Min` - stores the operand if it is smaller. Supports integers and floats. , .arguments = &.{ "comptime T: type", @@ -168,9 +192,9 @@ pub const builtins = [_]Builtin{ \\Asserts that `@typeInfo(DestType) != .Pointer`. Use `@ptrCast` or `@intToPtr` if you need this. \\ \\Can be used for these things for example: - \\ - Convert `f32` to `u32` bits - \\ - Convert `i32` to `u32` preserving twos complement \\ + \\ - Convert `f32` to `u32` bits + \\ - Convert `i32` to `u32` preserving twos complement \\Works at compile-time if `value` is known at compile time. It's a compile error to bitcast a value of undefined layout; this means that, besides the restriction from types which possess dedicated casting builtins (enums, pointers, error sets), bare structs, error unions, slices, optionals, and any other type without a well-defined memory layout, also cannot be used in this operation. , .arguments = &.{ @@ -298,17 +322,48 @@ pub const builtins = [_]Builtin{ \\ \\```zig \\const expect = @import("std").testing.expect; - \\ \\test "noinline function call" { \\ try expect(@call(.{}, add, .{3, 9}) == 12); \\} - \\ \\fn add(a: i32, b: i32) i32 { \\ return a + b; \\} \\``` + \\`@call` allows more flexibility than normal function call syntax does. The `CallOptions` struct is reproduced here: \\ - \\`@call` allows more flexibility than normal function call syntax does. The `CallOptions` struct is reproduced here:

{#syntax_block|zig|builtin.CallOptions struct#} pub const CallOptions = struct { modifier: Modifier = .auto, /// Only valid when `Modifier` is `Modifier.async_kw`. stack: ?[]align(std.Target.stack_align) u8 = null, pub const Modifier = enum { /// Equivalent to function call syntax. auto, /// Equivalent to async keyword used with function call syntax. async_kw, /// Prevents tail call optimization. This guarantees that the return /// address will point to the callsite, as opposed to the callsite's /// callsite. If the call is otherwise required to be tail-called /// or inlined, a compile error is emitted instead. never_tail, /// Guarantees that the call will not be inlined. If the call is /// otherwise required to be inlined, a compile error is emitted instead. never_inline, /// Asserts that the function call will not suspend. This allows a /// non-async function to call an async function. no_async, /// Guarantees that the call will be generated with tail call optimization. /// If this is not possible, a compile error is emitted instead. always_tail, /// Guarantees that the call will inlined at the callsite. /// If this is not possible, a compile error is emitted instead. always_inline, /// Evaluates the call at compile-time. If the call cannot be completed at /// compile-time, a compile error is emitted instead. compile_time, }; }; {#end_syntax_block#} + \\```zig + \\pub const CallOptions = struct { + \\ modifier: Modifier = .auto, + \\ /// Only valid when `Modifier` is `Modifier.async_kw`. + \\ stack: ?[]align(std.Target.stack_align) u8 = null, + \\ pub const Modifier = enum { + \\ /// Equivalent to function call syntax. + \\ auto, + \\ /// Equivalent to async keyword used with function call syntax. + \\ async_kw, + \\ /// Prevents tail call optimization. This guarantees that the return + \\ /// address will point to the callsite, as opposed to the callsite's + \\ /// callsite. If the call is otherwise required to be tail-called + \\ /// or inlined, a compile error is emitted instead. + \\ never_tail, + \\ /// Guarantees that the call will not be inlined. If the call is + \\ /// otherwise required to be inlined, a compile error is emitted instead. + \\ never_inline, + \\ /// Asserts that the function call will not suspend. This allows a + \\ /// non-async function to call an async function. + \\ no_async, + \\ /// Guarantees that the call will be generated with tail call optimization. + \\ /// If this is not possible, a compile error is emitted instead. + \\ always_tail, + \\ /// Guarantees that the call will inlined at the callsite. + \\ /// If this is not possible, a compile error is emitted instead. + \\ always_inline, + \\ /// Evaluates the call at compile-time. If the call cannot be completed at + \\ /// compile-time, a compile error is emitted instead. + \\ compile_time, + \\ }; + \\}; + \\``` , .arguments = &.{ "options: std.builtin.CallOptions", @@ -323,15 +378,14 @@ pub const builtins = [_]Builtin{ .documentation = \\This function can only occur inside `@cImport`. \\ - \\This appends `#define $name $value` to the `@cImport` temporary buffer. + \\This appends + \\`#define $name $value`to the `@cImport` temporary buffer. \\ - \\To define without a value, like this:`#define _GNU_SOURCE` + \\To define without a value, like this: \\ - \\Use the void value, like this: + \\`#define _GNU_SOURCE`Use the void value, like this: \\ - \\```zig - \\@cDefine("_GNU_SOURCE", {}) - \\``` + \\`@cDefine("_GNU_SOURCE", {})` , .arguments = &.{ "comptime name: []u8", @@ -350,8 +404,9 @@ pub const builtins = [_]Builtin{ \\Usually you should only have one `@cImport` in your entire application, because it saves the compiler from invoking clang multiple times, and prevents inline functions from being duplicated. \\ \\Reasons for having multiple `@cImport` expressions would be: - \\ - To avoid a symbol collision, for example if foo.h and bar.h both `#define CONNECTION_COUNT` - \\ - To analyze the C code with different preprocessor defines + \\ + \\ - To avoid a symbol collision, for example if foo.h and bar.h both + \\`#define CONNECTION_COUNT` - To analyze the C code with different preprocessor defines , .arguments = &.{ "expression", @@ -364,7 +419,8 @@ pub const builtins = [_]Builtin{ .documentation = \\This function can only occur inside `@cImport`. \\ - \\This appends `#include <$path>\n` to the `c_import` temporary buffer. + \\This appends + \\`#include <$path>\n`to the `c_import` temporary buffer. , .arguments = &.{ "comptime path: []u8", @@ -407,7 +463,6 @@ pub const builtins = [_]Builtin{ \\ } \\} \\``` - \\ \\If you are using cmpxchg in a loop, [@cmpxchgWeak](https://ziglang.org/documentation/0.10.0/#cmpxchgWeak) is the better choice, because it can be implemented more efficiently in machine instructions. \\ \\`T` must be a pointer, a `bool`, a float, an integer or an enum. @@ -428,8 +483,19 @@ pub const builtins = [_]Builtin{ .signature = "@cmpxchgWeak(comptime T: type, ptr: *T, expected_value: T, new_value: T, success_order: AtomicOrder, fail_order: AtomicOrder) ?T", .snippet = "@cmpxchgWeak(${1:comptime T: type}, ${2:ptr: *T}, ${3:expected_value: T}, ${4:new_value: T}, ${5:success_order: AtomicOrder}, ${6:fail_order: AtomicOrder})", .documentation = - \\This function performs a weak atomic compare exchange operation. It's the equivalent of this code, except atomic:

{#syntax_block|zig|cmpxchgWeakButNotAtomic#} fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_value: T) ?T { const old_value = ptr.*; if (old_value == expected_value and usuallyTrueButSometimesFalse()) { ptr.* = new_value; return null; } else { return old_value; } } {#end_syntax_block#} + \\This function performs a weak atomic compare exchange operation. It's the equivalent of this code, except atomic: \\ + \\```zig + \\fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_value: T) ?T { + \\ const old_value = ptr.*; + \\ if (old_value == expected_value and usuallyTrueButSometimesFalse()) { + \\ ptr.* = new_value; + \\ return null; + \\ } else { + \\ return old_value; + \\ } + \\} + \\``` \\If you are using cmpxchg in a loop, the sporadic failure will be no problem, and `cmpxchgWeak` is the better choice, because it can be implemented more efficiently in machine instructions. However if you need a stronger guarantee, use [@cmpxchgStrong](https://ziglang.org/documentation/0.10.0/#cmpxchgStrong). \\ \\`T` must be a pointer, a `bool`, a float, an integer or an enum. @@ -471,22 +537,30 @@ pub const builtins = [_]Builtin{ \\ \\```zig \\const print = @import("std").debug.print; - \\ \\const num1 = blk: { \\ var val1: i32 = 99; \\ @compileLog("comptime val1 = ", val1); \\ val1 = val1 + 1; \\ break :blk val1; \\}; - \\ \\test "main" { \\ @compileLog("comptime in main"); - \\ \\ print("Runtime in main, num1 = {}.\n", .{num1}); \\} \\``` + \\If all `@compileLog` calls are removed or not encountered by analysis, the program compiles successfully and the generated executable prints: \\ - \\If all `@compileLog` calls are removed or not encountered by analysis, the program compiles successfully and the generated executable prints:

{#code_begin|test|without_compileLog#} const print = @import("std").debug.print; const num1 = blk: { var val1: i32 = 99; val1 = val1 + 1; break :blk val1; }; test "main" { print("Runtime in main, num1 = {}.\n", .{num1}); }` + \\```zig + \\const print = @import("std").debug.print; + \\const num1 = blk: { + \\ var val1: i32 = 99; + \\ val1 = val1 + 1; + \\ break :blk val1; + \\}; + \\test "main" { + \\ print("Runtime in main, num1 = {}.\n", .{num1}); + \\} + \\``` , .arguments = &.{ "args: ...", @@ -518,7 +592,8 @@ pub const builtins = [_]Builtin{ .documentation = \\This function can only occur inside `@cImport`. \\ - \\This appends `#undef $name` to the `@cImport` temporary buffer. + \\This appends + \\`#undef $name`to the `@cImport` temporary buffer. , .arguments = &.{ "comptime name: []u8", @@ -530,9 +605,9 @@ pub const builtins = [_]Builtin{ .snippet = "@divExact(${1:numerator: T}, ${2:denominator: T})", .documentation = \\Exact division. Caller guarantees `denominator != 0` and `@divTrunc(numerator, denominator) * denominator == numerator`. - \\ - `@divExact(6, 3) == 2` - \\ - `@divExact(a, b) * b == a` \\ + \\ - `@divExact(6, 3) == 2` + \\ - `@divExact(a, b) * b == a` \\For a function that returns a possible error code, use `@import("std").math.divExact`. , .arguments = &.{ @@ -546,9 +621,9 @@ pub const builtins = [_]Builtin{ .snippet = "@divFloor(${1:numerator: T}, ${2:denominator: T})", .documentation = \\Floored division. Rounds toward negative infinity. For unsigned integers it is the same as `numerator / denominator`. Caller guarantees `denominator != 0` and `!(@typeInfo(T) == .Int and T.is_signed and numerator == std.math.minInt(T) and denominator == -1)`. - \\ - `@divFloor(-5, 3) == -2` - \\ - `(@divFloor(a, b) * b) + @mod(a, b) == a` \\ + \\ - `@divFloor(-5, 3) == -2` + \\ - `(@divFloor(a, b) * b) + @mod(a, b) == a` \\For a function that returns a possible error code, use `@import("std").math.divFloor`. , .arguments = &.{ @@ -562,9 +637,9 @@ pub const builtins = [_]Builtin{ .snippet = "@divTrunc(${1:numerator: T}, ${2:denominator: T})", .documentation = \\Truncated division. Rounds toward zero. For unsigned integers it is the same as `numerator / denominator`. Caller guarantees `denominator != 0` and `!(@typeInfo(T) == .Int and T.is_signed and numerator == std.math.minInt(T) and denominator == -1)`. - \\ - `@divTrunc(-5, 3) == -1` - \\ - `(@divTrunc(a, b) * b) + @rem(a, b) == a` \\ + \\ - `@divTrunc(-5, 3) == -1` + \\ - `(@divTrunc(a, b) * b) + @rem(a, b) == a` \\For a function that returns a possible error code, use `@import("std").math.divTrunc`. , .arguments = &.{ @@ -626,10 +701,10 @@ pub const builtins = [_]Builtin{ .snippet = "@errorToInt(${1:err: anytype})", .documentation = \\Supports the following types: - \\ - [The Global Error Set](https://ziglang.org/documentation/0.10.0/#The-Global-Error-Set) - \\ - [Error Set Type](https://ziglang.org/documentation/0.10.0/#Error-Set-Type) - \\ - [Error Union Type](https://ziglang.org/documentation/0.10.0/#Error-Union-Type) \\ + \\ - [The Global Error Set](https://ziglang.org/documentation/0.10.0/#The-Global-Error-Set) + \\ - [Error Set Type](https://ziglang.org/documentation/0.10.0/#Error-Set-Type) + \\ - [Error Union Type](https://ziglang.org/documentation/0.10.0/#Error-Union-Type) \\Converts an error to the integer representation of an error. \\ \\It is generally recommended to avoid this cast, as the integer representation of an error is not stable across source code changes. @@ -657,37 +732,28 @@ pub const builtins = [_]Builtin{ .documentation = \\Creates a symbol in the output object file. \\ - \\`declaration` must be one of two things: - \\ - An identifier (`x`) identifying a [function](https://ziglang.org/documentation/0.10.0/#Functions) or a [variable](https://ziglang.org/documentation/0.10.0/#Container-Level-Variables). - \\ - Field access (`x.y`) looking up a [function](https://ziglang.org/documentation/0.10.0/#Functions) or a [variable](https://ziglang.org/documentation/0.10.0/#Container-Level-Variables). + \\`declaration`must be one of two things: \\ - \\This builtin can be called from a [comptime](https://ziglang.org/documentation/0.10.0/#comptime) block to conditionally export symbols. When `declaration` is a function with the C calling convention and `options.linkage` is `Strong`, this is equivalent to the `export` keyword used on a function: + \\ - An identifier (`x`) identifying a [function](https://ziglang.org/documentation/0.10.0/#Functions) or a [variable](https://ziglang.org/documentation/0.10.0/#Container-Level-Variables). + \\ - Field access (`x.y`) looking up a [function](https://ziglang.org/documentation/0.10.0/#Functions) or a [variable](https://ziglang.org/documentation/0.10.0/#Container-Level-Variables). + \\This builtin can be called from a [comptime](https://ziglang.org/documentation/0.10.0/#comptime) block to conditionally export symbols. When + \\`declaration`is a function with the C calling convention and `options.linkage` is `Strong`, this is equivalent to the `export` keyword used on a function: \\ \\```zig \\comptime { \\ @export(internalName, .{ .name = "foo", .linkage = .Strong }); \\} - \\ \\fn internalName() callconv(.C) void {} \\``` - \\ \\This is equivalent to: \\ - \\```zig - \\export fn foo() void {} - \\``` - \\ + \\`export fn foo() void {}` \\Note that even when using `export`, the `@"foo"` syntax for [identifiers](https://ziglang.org/documentation/0.10.0/#Identifiers) can be used to choose any string for the symbol name: \\ - \\```zig - \\export fn @"A function name that is a complete sentence."() void {} - \\``` - \\ + \\`export fn @"A function name that is a complete sentence."() void {}` \\When looking at the resulting object, you can see the symbol is used verbatim: \\ - \\```zig - \\00000000000001f0 T A function name that is a complete sentence. - \\``` + \\`00000000000001f0 T A function name that is a complete sentence.` , .arguments = &.{ "declaration", @@ -724,7 +790,30 @@ pub const builtins = [_]Builtin{ .signature = "@field(lhs: anytype, comptime field_name: []const u8) (field)", .snippet = "@field(${1:lhs: anytype}, ${2:comptime field_name: []const u8})", .documentation = - \\Performs field access by a compile-time string. Works on both fields and declarations.

{#code_begin|test|field_decl_access_by_string#} const std = @import("std"); const Point = struct { x: u32, y: u32, pub var z: u32 = 1; }; test "field access by string" { const expect = std.testing.expect; var p = Point{ .x = 0, .y = 0 }; @field(p, "x") = 4; @field(p, "y") = @field(p, "x") + 1; try expect(@field(p, "x") == 4); try expect(@field(p, "y") == 5); } test "decl access by string" { const expect = std.testing.expect; try expect(@field(Point, "z") == 1); @field(Point, "z") = 2; try expect(@field(Point, "z") == 2); }` + \\Performs field access by a compile-time string. Works on both fields and declarations. + \\ + \\```zig + \\const std = @import("std"); + \\const Point = struct { + \\ x: u32, + \\ y: u32, + \\ pub var z: u32 = 1; + \\}; + \\test "field access by string" { + \\ const expect = std.testing.expect; + \\ var p = Point{ .x = 0, .y = 0 }; + \\ @field(p, "x") = 4; + \\ @field(p, "y") = @field(p, "x") + 1; + \\ try expect(@field(p, "x") == 4); + \\ try expect(@field(p, "y") == 5); + \\} + \\test "decl access by string" { + \\ const expect = std.testing.expect; + \\ try expect(@field(Point, "z") == 1); + \\ @field(Point, "z") = 2; + \\ try expect(@field(Point, "z") == 2); + \\} + \\``` , .arguments = &.{ "lhs: anytype", @@ -733,7 +822,7 @@ pub const builtins = [_]Builtin{ }, .{ .name = "@fieldParentPtr", - .signature = "@fieldParentPtr(comptime ParentType: type, comptime field_name: []const u8, field_ptr: *T) *ParentType", + .signature = "@fieldParentPtr(comptime ParentType: type, comptime field_name: []const u8, field_ptr: *T) *ParentType", .snippet = "@fieldParentPtr(${1:comptime ParentType: type}, ${2:comptime field_name: []const u8}, ${3:field_ptr: *T})", .documentation = \\Given a pointer to a field, returns the base pointer of a struct. @@ -788,7 +877,18 @@ pub const builtins = [_]Builtin{ .documentation = \\This function returns the frame type of a function. This works for [Async Functions](https://ziglang.org/documentation/0.10.0/#Async-Functions) as well as any function without a specific calling convention. \\ - \\This type is suitable to be used as the return type of [async](https://ziglang.org/documentation/0.10.0/#Async-and-Await) which allows one to, for example, heap-allocate an async function frame:

{#code_begin|test|heap_allocated_frame#} {#backend_stage1#} const std = @import("std"); test "heap allocated frame" { const frame = try std.heap.page_allocator.create(@Frame(func)); frame.* = async func(); } fn func() void { suspend {} }` + \\This type is suitable to be used as the return type of [async](https://ziglang.org/documentation/0.10.0/#Async-and-Await) which allows one to, for example, heap-allocate an async function frame: + \\ + \\```zig + \\const std = @import("std"); + \\test "heap allocated frame" { + \\ const frame = try std.heap.page_allocator.create(@Frame(func)); + \\ frame.* = async func(); + \\} + \\fn func() void { + \\ suspend {} + \\} + \\``` , .arguments = &.{ "func: anytype", @@ -825,7 +925,27 @@ pub const builtins = [_]Builtin{ .signature = "@hasDecl(comptime Container: type, comptime name: []const u8) bool", .snippet = "@hasDecl(${1:comptime Container: type}, ${2:comptime name: []const u8})", .documentation = - \\Returns whether or not a [struct](https://ziglang.org/documentation/0.10.0/#struct), [enum](https://ziglang.org/documentation/0.10.0/#enum), or [union](https://ziglang.org/documentation/0.10.0/#union) has a declaration matching `name`.

{#code_begin|test|hasDecl#} const std = @import("std"); const expect = std.testing.expect; const Foo = struct { nope: i32, pub var blah = "xxx"; const hi = 1; }; test "@hasDecl" { try expect(@hasDecl(Foo, "blah")); // Even though `hi` is private, @hasDecl returns true because this test is // in the same file scope as Foo. It would return false if Foo was declared // in a different file. try expect(@hasDecl(Foo, "hi")); // @hasDecl is for declarations; not fields. try expect(!@hasDecl(Foo, "nope")); try expect(!@hasDecl(Foo, "nope1234")); }` + \\Returns whether or not a [struct](https://ziglang.org/documentation/0.10.0/#struct), [enum](https://ziglang.org/documentation/0.10.0/#enum), or [union](https://ziglang.org/documentation/0.10.0/#union) has a declaration matching `name`. + \\ + \\```zig + \\const std = @import("std"); + \\const expect = std.testing.expect; + \\const Foo = struct { + \\ nope: i32, + \\ pub var blah = "xxx"; + \\ const hi = 1; + \\}; + \\test "@hasDecl" { + \\ try expect(@hasDecl(Foo, "blah")); + \\ // Even though `hi` is private, @hasDecl returns true because this test is + \\ // in the same file scope as Foo. It would return false if Foo was declared + \\ // in a different file. + \\ try expect(@hasDecl(Foo, "hi")); + \\ // @hasDecl is for declarations; not fields. + \\ try expect(!@hasDecl(Foo, "nope")); + \\ try expect(!@hasDecl(Foo, "nope1234")); + \\} + \\``` , .arguments = &.{ "comptime Container: type", @@ -862,9 +982,12 @@ pub const builtins = [_]Builtin{ \\`path` can be a relative path or it can be the name of a package. If it is a relative path, it is relative to the file that contains the `@import` function call. \\ \\The following packages are always available: - \\ - `@import("std")` - Zig Standard Library - \\ - `@import("builtin")` - Target-specific information. The command `zig build-exe --show-builtin` outputs the source to stdout for reference. - \\ - `@import("root")` - Points to the root source file. This is usually `src/main.zig` but it depends on what file is chosen to be built. + \\ + \\ - `@import("std")` - Zig Standard Library + \\ - `@import("builtin")` - Target-specific information. The command + \\`zig build-exe --show-builtin`outputs the source to stdout for reference. + \\ - `@import("root")` - Points to the root source file. This is usually + \\`src/main.zig`but it depends on what file is chosen to be built. , .arguments = &.{ "comptime path: []u8", @@ -884,7 +1007,6 @@ pub const builtins = [_]Builtin{ \\ _ = b; \\} \\``` - \\ \\To truncate the significant bits of a number out of range of the destination type, use [@truncate](https://ziglang.org/documentation/0.10.0/#truncate). \\ \\If `T` is `comptime_int`, then this is semantically equivalent to [Type Coercion](https://ziglang.org/documentation/0.10.0/#Type-Coercion). @@ -911,7 +1033,7 @@ pub const builtins = [_]Builtin{ .{ .name = "@intToError", .signature = "@intToError(value: std.meta.Int(.unsigned, @sizeOf(anyerror) * 8)) anyerror", - .snippet = "@intToError(${1:value: std.meta.Int(.unsigned, @sizeOf(anyerror) * 8)})", + .snippet = "@intToError(${1:value: std.meta.Int(.unsigned, @sizeOf(anyerror) * 8})", .documentation = \\Converts from the integer representation of an error into [The Global Error Set](https://ziglang.org/documentation/0.10.0/#The-Global-Error-Set) type. \\ @@ -920,7 +1042,7 @@ pub const builtins = [_]Builtin{ \\Attempting to convert an integer that does not correspond to any error results in safety-protected [Undefined Behavior](https://ziglang.org/documentation/0.10.0/#Undefined-Behavior). , .arguments = &.{ - "value: std.meta.Int(.unsigned, @sizeOf(anyerror) * 8)", + "value: std.meta.Int(.unsigned, @sizeOf(anyerror) * 8", }, }, .{ @@ -972,10 +1094,7 @@ pub const builtins = [_]Builtin{ \\ \\This function is a low level intrinsic with no safety mechanisms. Most code should not use this function, instead using something like this: \\ - \\```zig - \\for (source[0..byte_count]) |b, i| dest[i] = b; - \\``` - \\ + \\`for (source[0..byte_count]) |b, i| dest[i] = b;` \\The optimizer is intelligent enough to turn the above snippet into a memcpy. \\ \\There is also a standard library function for this: @@ -1000,10 +1119,7 @@ pub const builtins = [_]Builtin{ \\ \\This function is a low level intrinsic with no safety mechanisms. Most code should not use this function, instead using something like this: \\ - \\```zig - \\for (dest[0..byte_count]) |*b| b.* = c; - \\``` - \\ + \\`for (dest[0..byte_count]) |*b| b.* = c;` \\The optimizer is intelligent enough to turn the above snippet into a memset. \\ \\There is also a standard library function for this: @@ -1053,7 +1169,19 @@ pub const builtins = [_]Builtin{ .documentation = \\This function increases the size of the Wasm memory identified by `index` by `delta` in units of unsigned number of Wasm pages. Note that each Wasm page is 64KB in size. On success, returns previous memory size; on failure, if the allocation fails, returns -1. \\ - \\This function is a low level intrinsic with no safety mechanisms usually useful for allocator designers targeting Wasm. So unless you are writing a new allocator from scratch, you should use something like `@import("std").heap.WasmPageAllocator`.

{#code_begin|test|wasmMemoryGrow#} const std = @import("std"); const native_arch = @import("builtin").target.cpu.arch; const expect = std.testing.expect; test "@wasmMemoryGrow" { if (native_arch != .wasm32) return error.SkipZigTest; var prev = @wasmMemorySize(0); try expect(prev == @wasmMemoryGrow(0, 1)); try expect(prev + 1 == @wasmMemorySize(0)); }` + \\This function is a low level intrinsic with no safety mechanisms usually useful for allocator designers targeting Wasm. So unless you are writing a new allocator from scratch, you should use something like `@import("std").heap.WasmPageAllocator`. + \\ + \\```zig + \\const std = @import("std"); + \\const native_arch = @import("builtin").target.cpu.arch; + \\const expect = std.testing.expect; + \\test "@wasmMemoryGrow" { + \\ if (native_arch != .wasm32) return error.SkipZigTest; + \\ var prev = @wasmMemorySize(0); + \\ try expect(prev == @wasmMemoryGrow(0, 1)); + \\ try expect(prev + 1 == @wasmMemorySize(0)); + \\} + \\``` , .arguments = &.{ "index: u32", @@ -1066,9 +1194,9 @@ pub const builtins = [_]Builtin{ .snippet = "@mod(${1:numerator: T}, ${2:denominator: T})", .documentation = \\Modulus division. For unsigned integers this is the same as `numerator % denominator`. Caller guarantees `denominator > 0`, otherwise the operation will result in a [Remainder Division by Zero](https://ziglang.org/documentation/0.10.0/#Remainder-Division-by-Zero) when runtime safety checks are enabled. - \\ - `@mod(-5, 3) == 1` - \\ - `(@divFloor(a, b) * b) + @mod(a, b) == a` \\ + \\ - `@mod(-5, 3) == 1` + \\ - `(@divFloor(a, b) * b) + @mod(a, b) == a` \\For a function that returns an error code, see `@import("std").math.mod`. , .arguments = &.{ @@ -1098,8 +1226,9 @@ pub const builtins = [_]Builtin{ \\Invokes the panic handler function. By default the panic handler function calls the public `panic` function exposed in the root source file, or if there is not one specified, the `std.builtin.default_panic` function from `std/builtin.zig`. \\ \\Generally it is better to use `@import("std").debug.panic`. However, `@panic` can be useful for 2 scenarios: - \\ - From library code, calling the programmer's panic function if they exposed one in the root source file. - \\ - When mixing C and Zig code, calling the canonical panic implementation across multiple .o files. + \\ + \\ - From library code, calling the programmer's panic function if they exposed one in the root source file. + \\ - When mixing C and Zig code, calling the canonical panic implementation across multiple .o files. , .arguments = &.{ "message: []const u8", @@ -1131,7 +1260,32 @@ pub const builtins = [_]Builtin{ \\ \\The `ptr` argument may be any pointer type and determines the memory address to prefetch. This function does not dereference the pointer, it is perfectly legal to pass a pointer to invalid memory to this function and no illegal behavior will result. \\ - \\The `options` argument is the following struct:

{#code_begin|syntax|builtin#} /// This data structure is used by the Zig language code generation and /// therefore must be kept in sync with the compiler implementation. pub const PrefetchOptions = struct { /// Whether the prefetch should prepare for a read or a write. rw: Rw = .read, /// 0 means no temporal locality. That is, the data can be immediately /// dropped from the cache after it is accessed. /// /// 3 means high temporal locality. That is, the data should be kept in /// the cache as it is likely to be accessed again soon. locality: u2 = 3, /// The cache that the prefetch should be preformed on. cache: Cache = .data, pub const Rw = enum { read, write, }; pub const Cache = enum { instruction, data, }; };` + \\The `options` argument is the following struct: + \\ + \\```zig + \\/// This data structure is used by the Zig language code generation and + \\/// therefore must be kept in sync with the compiler implementation. + \\pub const PrefetchOptions = struct { + \\ /// Whether the prefetch should prepare for a read or a write. + \\ rw: Rw = .read, + \\ /// 0 means no temporal locality. That is, the data can be immediately + \\ /// dropped from the cache after it is accessed. + \\ /// + \\ /// 3 means high temporal locality. That is, the data should be kept in + \\ /// the cache as it is likely to be accessed again soon. + \\ locality: u2 = 3, + \\ /// The cache that the prefetch should be preformed on. + \\ cache: Cache = .data, + \\ pub const Rw = enum { + \\ read, + \\ write, + \\ }; + \\ pub const Cache = enum { + \\ instruction, + \\ data, + \\ }; + \\}; + \\``` , .arguments = &.{ "ptr: anytype", @@ -1171,9 +1325,9 @@ pub const builtins = [_]Builtin{ .snippet = "@rem(${1:numerator: T}, ${2:denominator: T})", .documentation = \\Remainder division. For unsigned integers this is the same as `numerator % denominator`. Caller guarantees `denominator > 0`, otherwise the operation will result in a [Remainder Division by Zero](https://ziglang.org/documentation/0.10.0/#Remainder-Division-by-Zero) when runtime safety checks are enabled. - \\ - `@rem(-5, 3) == -2` - \\ - `(@divTrunc(a, b) * b) + @rem(a, b) == a` \\ + \\ - `@rem(-5, 3) == -2` + \\ - `(@divTrunc(a, b) * b) + @rem(a, b) == a` \\For a function that returns an error code, see `@import("std").math.rem`. , .arguments = &.{ @@ -1241,16 +1395,16 @@ pub const builtins = [_]Builtin{ \\ \\Example: \\ - \\```zig - \\test "foo" { - \\ comptime { - \\ var i = 0; - \\ while (i < 1001) : (i += 1) {} + \\1001) : (i += 1) {} \\ } \\} \\``` + \\Now we use `@setEvalBranchQuota`: \\ - \\Now we use `@setEvalBranchQuota`:

{#code_begin|test|setEvalBranchQuota#} test "foo" { comptime { @setEvalBranchQuota(1001); var i = 0; while (i < 1001) : (i += 1) {} } }` + \\1001) : (i += 1) {} + \\ } + \\} + \\``` , .arguments = &.{ "comptime new_quota: u32", @@ -1269,16 +1423,16 @@ pub const builtins = [_]Builtin{ \\ Optimized, \\}; \\``` - \\ - \\ - `Strict` (default) - Floating point operations follow strict IEEE compliance. - \\ - `Optimized` - Floating point operations may do all of the following:
    - \\ - Assume the arguments and result are not NaN. Optimizations are required to retain defined behavior over NaNs, but the value of the result is undefined. - \\ - Assume the arguments and result are not +/-Inf. Optimizations are required to retain defined behavior over +/-Inf, but the value of the result is undefined. - \\ - Treat the sign of a zero argument or result as insignificant. - \\ - Use the reciprocal of an argument rather than perform division. - \\ - Perform floating-point contraction (e.g. fusing a multiply followed by an addition into a fused multiply-add). - \\ - Perform algebraically equivalent transformations that may change results in floating point (e.g. reassociate). This is equivalent to `-ffast-math` in GCC.
- \\ + \\ - `Strict` (default) - Floating point operations follow strict IEEE compliance. + \\ - `Optimized` - Floating point operations may do all of the following: + \\ - Assume the arguments and result are not NaN. Optimizations are required to retain defined behavior over NaNs, but the value of the result is undefined. + \\ - Assume the arguments and result are not +/-Inf. Optimizations are required to retain defined behavior over +/-Inf, but the value of the result is undefined. + \\ - Treat the sign of a zero argument or result as insignificant. + \\ - Use the reciprocal of an argument rather than perform division. + \\ - Perform floating-point contraction (e.g. fusing a multiply followed by an addition into a fused multiply-add). + \\ - Perform algebraically equivalent transformations that may change results in floating point (e.g. reassociate). + \\This is equivalent to + \\`-ffast-math`in GCC. \\The floating point mode is inherited by child scopes, and can be overridden in any scope. You can set the floating point mode in a struct or module scope by using a comptime block. , .arguments = &.{ @@ -1304,7 +1458,6 @@ pub const builtins = [_]Builtin{ \\ @setRuntimeSafety(true); \\ var x: u8 = 255; \\ x += 1; - \\ \\ { \\ // The value can be overridden at any scope. So here integer overflow \\ // would not be caught in any build mode. @@ -1315,8 +1468,9 @@ pub const builtins = [_]Builtin{ \\ } \\} \\``` - \\ - \\Note: it is [planned](https://github.com/ziglang/zig/issues/978) to replace `@setRuntimeSafety` with `@optimizeFor` + \\Note: it is + \\[planned](https://github.com/ziglang/zig/issues/978)to replace `@setRuntimeSafety` with + \\`@optimizeFor` , .arguments = &.{ "comptime safety_on: bool", @@ -1327,7 +1481,7 @@ pub const builtins = [_]Builtin{ .signature = "@shlExact(value: T, shift_amt: Log2T) T", .snippet = "@shlExact(${1:value: T}, ${2:shift_amt: Log2T})", .documentation = - \\Performs the left shift operation (`<<`). For unsigned integers, the result is [undefined](https://ziglang.org/documentation/0.10.0/#undefined) if any 1 bits are shifted out. For signed integers, the result is [undefined](https://ziglang.org/documentation/0.10.0/#undefined) if any bits that disagree with the resultant sign bit are shifted out. + \\`). For unsigned integers, the result is [undefined](https://ziglang.org/documentation/0.10.0/#undefined) if any 1 bits are shifted out. For signed integers, the result is [undefined](https://ziglang.org/documentation/0.10.0/#undefined) if any bits that disagree with the resultant sign bit are shifted out. \\ \\The type of `shift_amt` is an unsigned integer with `log2(@typeInfo(T).Int.bits)` bits. This is because `shift_amt >= @typeInfo(T).Int.bits` is undefined behavior. , @@ -1341,7 +1495,7 @@ pub const builtins = [_]Builtin{ .signature = "@shlWithOverflow(comptime T: type, a: T, shift_amt: Log2T, result: *T) bool", .snippet = "@shlWithOverflow(${1:comptime T: type}, ${2:a: T}, ${3:shift_amt: Log2T}, ${4:result: *T})", .documentation = - \\Performs `result.* = a << b`. If overflow or underflow occurs, stores the overflowed bits in `result` and returns `true`. If no overflow or underflow occurs, returns `false`. + \\b`. If overflow or underflow occurs, stores the overflowed bits in `result` and returns `true`. If no overflow or underflow occurs, returns `false`. \\ \\The type of `shift_amt` is an unsigned integer with `log2(@typeInfo(T).Int.bits)` bits. This is because `shift_amt >= @typeInfo(T).Int.bits` is undefined behavior. , @@ -1381,7 +1535,25 @@ pub const builtins = [_]Builtin{ \\ \\If `a` or `b` is `undefined`, it is equivalent to a vector of all `undefined` with the same length as the other vector. If both vectors are `undefined`, `@shuffle` returns a vector with all elements `undefined`. \\ - \\`E` must be an [integer](https://ziglang.org/documentation/0.10.0/#Integers), [float](https://ziglang.org/documentation/0.10.0/#Floats), [pointer](https://ziglang.org/documentation/0.10.0/#Pointers), or `bool`. The mask may be any vector length, and its length determines the result length.

{#code_begin|test|vector_shuffle#} const std = @import("std"); const expect = std.testing.expect; test "vector @shuffle" { const a = @Vector(7, u8){ 'o', 'l', 'h', 'e', 'r', 'z', 'w' }; const b = @Vector(4, u8){ 'w', 'd', '!', 'x' }; // To shuffle within a single vector, pass undefined as the second argument. // Notice that we can re-order, duplicate, or omit elements of the input vector const mask1 = @Vector(5, i32){ 2, 3, 1, 1, 0 }; const res1: @Vector(5, u8) = @shuffle(u8, a, undefined, mask1); try expect(std.mem.eql(u8, &@as([5]u8, res1), "hello")); // Combining two vectors const mask2 = @Vector(6, i32){ -1, 0, 4, 1, -2, -3 }; const res2: @Vector(6, u8) = @shuffle(u8, a, b, mask2); try expect(std.mem.eql(u8, &@as([6]u8, res2), "world!")); }` + \\`E` must be an [integer](https://ziglang.org/documentation/0.10.0/#Integers), [float](https://ziglang.org/documentation/0.10.0/#Floats), [pointer](https://ziglang.org/documentation/0.10.0/#Pointers), or `bool`. The mask may be any vector length, and its length determines the result length. + \\ + \\```zig + \\const std = @import("std"); + \\const expect = std.testing.expect; + \\test "vector @shuffle" { + \\ const a = @Vector(7, u8){ 'o', 'l', 'h', 'e', 'r', 'z', 'w' }; + \\ const b = @Vector(4, u8){ 'w', 'd', '!', 'x' }; + \\ // To shuffle within a single vector, pass undefined as the second argument. + \\ // Notice that we can re-order, duplicate, or omit elements of the input vector + \\ const mask1 = @Vector(5, i32){ 2, 3, 1, 1, 0 }; + \\ const res1: @Vector(5, u8) = @shuffle(u8, a, undefined, mask1); + \\ try expect(std.mem.eql(u8, &@as([5]u8, res1), "hello")); + \\ // Combining two vectors + \\ const mask2 = @Vector(6, i32){ -1, 0, 4, 1, -2, -3 }; + \\ const res2: @Vector(6, u8) = @shuffle(u8, a, b, mask2); + \\ try expect(std.mem.eql(u8, &@as([6]u8, res2), "world!")); + \\} + \\``` , .arguments = &.{ "comptime E: type", @@ -1410,8 +1582,18 @@ pub const builtins = [_]Builtin{ .signature = "@splat(comptime len: u32, scalar: anytype) @Vector(len, @TypeOf(scalar))", .snippet = "@splat(${1:comptime len: u32}, ${2:scalar: anytype})", .documentation = - \\Produces a vector of length `len` where each element is the value `scalar`:

{#code_begin|test|vector_splat#} const std = @import("std"); const expect = std.testing.expect; test "vector @splat" { const scalar: u32 = 5; const result = @splat(4, scalar); comptime try expect(@TypeOf(result) == @Vector(4, u32)); try expect(std.mem.eql(u32, &@as([4]u32, result), &[_]u32{ 5, 5, 5, 5 })); }` + \\Produces a vector of length `len` where each element is the value `scalar`: \\ + \\```zig + \\const std = @import("std"); + \\const expect = std.testing.expect; + \\test "vector @splat" { + \\ const scalar: u32 = 5; + \\ const result = @splat(4, scalar); + \\ comptime try expect(@TypeOf(result) == @Vector(4, u32)); + \\ try expect(std.mem.eql(u32, &@as([4]u32, result), &[_]u32{ 5, 5, 5, 5 })); + \\} + \\``` \\`scalar` must be an [integer](https://ziglang.org/documentation/0.10.0/#Integers), [bool](https://ziglang.org/documentation/0.10.0/#Primitive-Types), [float](https://ziglang.org/documentation/0.10.0/#Floats), or [pointer](https://ziglang.org/documentation/0.10.0/#Pointers). , .arguments = &.{ @@ -1424,14 +1606,29 @@ pub const builtins = [_]Builtin{ .signature = "@reduce(comptime op: std.builtin.ReduceOp, value: anytype) E", .snippet = "@reduce(${1:comptime op: std.builtin.ReduceOp}, ${2:value: anytype})", .documentation = - \\Transforms a [vector](https://ziglang.org/documentation/0.10.0/#Vectors) into a scalar value (of type `E`) by performing a sequential horizontal reduction of its elements using the specified operator `op`. + \\Transforms a [vector](https://ziglang.org/documentation/0.10.0/#Vectors) into a scalar value (of type + \\`E`) by performing a sequential horizontal reduction of its elements using the specified operator `op`. \\ \\Not every operator is available for every vector element type: - \\ - Every operator is available for [integer](https://ziglang.org/documentation/0.10.0/#Integers) vectors. - \\ - `.And`, `.Or`, `.Xor` are additionally available for `bool` vectors, - \\ - `.Min`, `.Max`, `.Add`, `.Mul` are additionally available for [floating point](https://ziglang.org/documentation/0.10.0/#Floats) vectors, \\ - \\Note that `.Add` and `.Mul` reductions on integral types are wrapping; when applied on floating point types the operation associativity is preserved, unless the float mode is set to `Optimized`.

{#code_begin|test|vector_reduce#} const std = @import("std"); const expect = std.testing.expect; test "vector @reduce" { const value = @Vector(4, i32){ 1, -1, 1, -1 }; const result = value > @splat(4, @as(i32, 0)); // result is { true, false, true, false }; comptime try expect(@TypeOf(result) == @Vector(4, bool)); const is_all_true = @reduce(.And, result); comptime try expect(@TypeOf(is_all_true) == bool); try expect(is_all_true == false); }` + \\ - Every operator is available for [integer](https://ziglang.org/documentation/0.10.0/#Integers) vectors. + \\ - `.And`, `.Or`, `.Xor` are additionally available for `bool` vectors, + \\ - `.Min`, `.Max`, `.Add`, `.Mul` are additionally available for [floating point](https://ziglang.org/documentation/0.10.0/#Floats) vectors, + \\Note that `.Add` and `.Mul` reductions on integral types are wrapping; when applied on floating point types the operation associativity is preserved, unless the float mode is set to `Optimized`. + \\ + \\```zig + \\const std = @import("std"); + \\const expect = std.testing.expect; + \\test "vector @reduce" { + \\ const value = @Vector(4, i32){ 1, -1, 1, -1 }; + \\ const result = value > @splat(4, @as(i32, 0)); + \\ // result is { true, false, true, false }; + \\ comptime try expect(@TypeOf(result) == @Vector(4, bool)); + \\ const is_all_true = @reduce(.And, result); + \\ comptime try expect(@TypeOf(is_all_true) == bool); + \\ try expect(is_all_true == false); + \\} + \\``` , .arguments = &.{ "comptime op: std.builtin.ReduceOp", @@ -1443,7 +1640,22 @@ pub const builtins = [_]Builtin{ .signature = "@src() std.builtin.SourceLocation", .snippet = "@src()", .documentation = - \\Returns a `SourceLocation` struct representing the function's name and location in the source code. This must be called in a function.

{#code_begin|test|source_location#} const std = @import("std"); const expect = std.testing.expect; test "@src" { try doTheTest(); } fn doTheTest() !void { const src = @src(); try expect(src.line == 9); try expect(src.column == 17); try expect(std.mem.endsWith(u8, src.fn_name, "doTheTest")); try expect(std.mem.endsWith(u8, src.file, "source_location.zig")); }` + \\Returns a `SourceLocation` struct representing the function's name and location in the source code. This must be called in a function. + \\ + \\```zig + \\const std = @import("std"); + \\const expect = std.testing.expect; + \\test "@src" { + \\ try doTheTest(); + \\} + \\fn doTheTest() !void { + \\ const src = @src(); + \\ try expect(src.line == 9); + \\ try expect(src.column == 17); + \\ try expect(std.mem.endsWith(u8, src.fn_name, "doTheTest")); + \\ try expect(std.mem.endsWith(u8, src.file, "source_location.zig")); + \\} + \\``` , .arguments = &.{}, }, @@ -1454,7 +1666,8 @@ pub const builtins = [_]Builtin{ .documentation = \\Performs the square root of a floating point number. Uses a dedicated hardware instruction when available. \\ - \\Supports [Floats](https://ziglang.org/documentation/0.10.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.10.0/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). + \\Supports [Floats](https://ziglang.org/documentation/0.10.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.10.0/#Vectors) of floats, with the caveat that + \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). , .arguments = &.{ "value: anytype", @@ -1467,7 +1680,8 @@ pub const builtins = [_]Builtin{ .documentation = \\Sine trigonometric function on a floating point number. Uses a dedicated hardware instruction when available. \\ - \\Supports [Floats](https://ziglang.org/documentation/0.10.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.10.0/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). + \\Supports [Floats](https://ziglang.org/documentation/0.10.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.10.0/#Vectors) of floats, with the caveat that + \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). , .arguments = &.{ "value: anytype", @@ -1480,7 +1694,8 @@ pub const builtins = [_]Builtin{ .documentation = \\Cosine trigonometric function on a floating point number. Uses a dedicated hardware instruction when available. \\ - \\Supports [Floats](https://ziglang.org/documentation/0.10.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.10.0/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). + \\Supports [Floats](https://ziglang.org/documentation/0.10.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.10.0/#Vectors) of floats, with the caveat that + \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). , .arguments = &.{ "value: anytype", @@ -1493,7 +1708,8 @@ pub const builtins = [_]Builtin{ .documentation = \\Tangent trigonometric function on a floating point number. Uses a dedicated hardware instruction when available. \\ - \\Supports [Floats](https://ziglang.org/documentation/0.10.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.10.0/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). + \\Supports [Floats](https://ziglang.org/documentation/0.10.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.10.0/#Vectors) of floats, with the caveat that + \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). , .arguments = &.{ "value: anytype", @@ -1506,7 +1722,8 @@ pub const builtins = [_]Builtin{ .documentation = \\Base-e exponential function on a floating point number. Uses a dedicated hardware instruction when available. \\ - \\Supports [Floats](https://ziglang.org/documentation/0.10.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.10.0/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). + \\Supports [Floats](https://ziglang.org/documentation/0.10.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.10.0/#Vectors) of floats, with the caveat that + \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). , .arguments = &.{ "value: anytype", @@ -1519,7 +1736,8 @@ pub const builtins = [_]Builtin{ .documentation = \\Base-2 exponential function on a floating point number. Uses a dedicated hardware instruction when available. \\ - \\Supports [Floats](https://ziglang.org/documentation/0.10.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.10.0/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). + \\Supports [Floats](https://ziglang.org/documentation/0.10.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.10.0/#Vectors) of floats, with the caveat that + \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). , .arguments = &.{ "value: anytype", @@ -1532,7 +1750,8 @@ pub const builtins = [_]Builtin{ .documentation = \\Returns the natural logarithm of a floating point number. Uses a dedicated hardware instruction when available. \\ - \\Supports [Floats](https://ziglang.org/documentation/0.10.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.10.0/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). + \\Supports [Floats](https://ziglang.org/documentation/0.10.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.10.0/#Vectors) of floats, with the caveat that + \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). , .arguments = &.{ "value: anytype", @@ -1545,7 +1764,8 @@ pub const builtins = [_]Builtin{ .documentation = \\Returns the logarithm to the base 2 of a floating point number. Uses a dedicated hardware instruction when available. \\ - \\Supports [Floats](https://ziglang.org/documentation/0.10.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.10.0/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). + \\Supports [Floats](https://ziglang.org/documentation/0.10.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.10.0/#Vectors) of floats, with the caveat that + \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). , .arguments = &.{ "value: anytype", @@ -1558,7 +1778,8 @@ pub const builtins = [_]Builtin{ .documentation = \\Returns the logarithm to the base 10 of a floating point number. Uses a dedicated hardware instruction when available. \\ - \\Supports [Floats](https://ziglang.org/documentation/0.10.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.10.0/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). + \\Supports [Floats](https://ziglang.org/documentation/0.10.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.10.0/#Vectors) of floats, with the caveat that + \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). , .arguments = &.{ "value: anytype", @@ -1571,7 +1792,8 @@ pub const builtins = [_]Builtin{ .documentation = \\Returns the absolute value of a floating point number. Uses a dedicated hardware instruction when available. \\ - \\Supports [Floats](https://ziglang.org/documentation/0.10.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.10.0/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). + \\Supports [Floats](https://ziglang.org/documentation/0.10.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.10.0/#Vectors) of floats, with the caveat that + \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). , .arguments = &.{ "value: anytype", @@ -1584,7 +1806,8 @@ pub const builtins = [_]Builtin{ .documentation = \\Returns the largest integral value not greater than the given floating point number. Uses a dedicated hardware instruction when available. \\ - \\Supports [Floats](https://ziglang.org/documentation/0.10.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.10.0/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). + \\Supports [Floats](https://ziglang.org/documentation/0.10.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.10.0/#Vectors) of floats, with the caveat that + \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). , .arguments = &.{ "value: anytype", @@ -1597,7 +1820,8 @@ pub const builtins = [_]Builtin{ .documentation = \\Returns the smallest integral value not less than the given floating point number. Uses a dedicated hardware instruction when available. \\ - \\Supports [Floats](https://ziglang.org/documentation/0.10.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.10.0/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). + \\Supports [Floats](https://ziglang.org/documentation/0.10.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.10.0/#Vectors) of floats, with the caveat that + \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). , .arguments = &.{ "value: anytype", @@ -1610,7 +1834,8 @@ pub const builtins = [_]Builtin{ .documentation = \\Rounds the given floating point number to an integer, towards zero. Uses a dedicated hardware instruction when available. \\ - \\Supports [Floats](https://ziglang.org/documentation/0.10.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.10.0/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). + \\Supports [Floats](https://ziglang.org/documentation/0.10.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.10.0/#Vectors) of floats, with the caveat that + \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). , .arguments = &.{ "value: anytype", @@ -1623,7 +1848,8 @@ pub const builtins = [_]Builtin{ .documentation = \\Rounds the given floating point number to an integer, away from zero. Uses a dedicated hardware instruction when available. \\ - \\Supports [Floats](https://ziglang.org/documentation/0.10.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.10.0/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). + \\Supports [Floats](https://ziglang.org/documentation/0.10.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.10.0/#Vectors) of floats, with the caveat that + \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). , .arguments = &.{ "value: anytype", @@ -1661,8 +1887,26 @@ pub const builtins = [_]Builtin{ .signature = "@This() type", .snippet = "@This()", .documentation = - \\Returns the innermost struct, enum, or union that this function call is inside. This can be useful for an anonymous struct that needs to refer to itself:

{#code_begin|test|this_innermost#} const std = @import("std"); const expect = std.testing.expect; test "@This()" { var items = [_]i32{ 1, 2, 3, 4 }; const list = List(i32){ .items = items[0..] }; try expect(list.length() == 4); } fn List(comptime T: type) type { return struct { const Self = @This(); items: []T, fn length(self: Self) usize { return self.items.len; } }; }` + \\Returns the innermost struct, enum, or union that this function call is inside. This can be useful for an anonymous struct that needs to refer to itself: \\ + \\```zig + \\const std = @import("std"); + \\const expect = std.testing.expect; + \\test "@This()" { + \\ var items = [_]i32{ 1, 2, 3, 4 }; + \\ const list = List(i32){ .items = items[0..] }; + \\ try expect(list.length() == 4); + \\} + \\fn List(comptime T: type) type { + \\ return struct { + \\ const Self = @This(); + \\ items: []T, + \\ fn length(self: Self) usize { + \\ return self.items.len; + \\ } + \\ }; + \\} + \\``` \\When `@This()` is used at file scope, it returns a reference to the struct that corresponds to the current file. , .arguments = &.{}, @@ -1681,14 +1925,12 @@ pub const builtins = [_]Builtin{ \\```zig \\const std = @import("std"); \\const expect = std.testing.expect; - \\ \\test "integer truncation" { \\ var a: u16 = 0xabcd; \\ var b: u8 = @truncate(u8, a); \\ try expect(b == 0xcd); \\} \\``` - \\ \\Use [@intCast](https://ziglang.org/documentation/0.10.0/#intCast) to convert numbers guaranteed to fit the destination type. , .arguments = &.{ @@ -1704,33 +1946,34 @@ pub const builtins = [_]Builtin{ \\This function is the inverse of [@typeInfo](https://ziglang.org/documentation/0.10.0/#typeInfo). It reifies type information into a `type`. \\ \\It is available for the following types: - \\ - `type` - \\ - `noreturn` - \\ - `void` - \\ - `bool` - \\ - [Integers](https://ziglang.org/documentation/0.10.0/#Integers) - The maximum bit count for an integer type is `65535`. - \\ - [Floats](https://ziglang.org/documentation/0.10.0/#Floats) - \\ - [Pointers](https://ziglang.org/documentation/0.10.0/#Pointers) - \\ - `comptime_int` - \\ - `comptime_float` - \\ - `@TypeOf(undefined)` - \\ - `@TypeOf(null)` - \\ - [Arrays](https://ziglang.org/documentation/0.10.0/#Arrays) - \\ - [Optionals](https://ziglang.org/documentation/0.10.0/#Optionals) - \\ - [Error Set Type](https://ziglang.org/documentation/0.10.0/#Error-Set-Type) - \\ - [Error Union Type](https://ziglang.org/documentation/0.10.0/#Error-Union-Type) - \\ - [Vectors](https://ziglang.org/documentation/0.10.0/#Vectors) - \\ - [opaque](https://ziglang.org/documentation/0.10.0/#opaque) - \\ - [@Frame](https://ziglang.org/documentation/0.10.0/#Frame) - \\ - `anyframe` - \\ - [struct](https://ziglang.org/documentation/0.10.0/#struct) - \\ - [enum](https://ziglang.org/documentation/0.10.0/#enum) - \\ - [Enum Literals](https://ziglang.org/documentation/0.10.0/#Enum-Literals) - \\ - [union](https://ziglang.org/documentation/0.10.0/#union) \\ + \\ - `type` + \\ - `noreturn` + \\ - `void` + \\ - `bool` + \\ - [Integers](https://ziglang.org/documentation/0.10.0/#Integers) - The maximum bit count for an integer type is `65535`. + \\ - [Floats](https://ziglang.org/documentation/0.10.0/#Floats) + \\ - [Pointers](https://ziglang.org/documentation/0.10.0/#Pointers) + \\ - `comptime_int` + \\ - `comptime_float` + \\ - `@TypeOf(undefined)` + \\ - `@TypeOf(null)` + \\ - [Arrays](https://ziglang.org/documentation/0.10.0/#Arrays) + \\ - [Optionals](https://ziglang.org/documentation/0.10.0/#Optionals) + \\ - [Error Set Type](https://ziglang.org/documentation/0.10.0/#Error-Set-Type) + \\ - [Error Union Type](https://ziglang.org/documentation/0.10.0/#Error-Union-Type) + \\ - [Vectors](https://ziglang.org/documentation/0.10.0/#Vectors) + \\ - [opaque](https://ziglang.org/documentation/0.10.0/#opaque) + \\ - [@Frame](https://ziglang.org/documentation/0.10.0/#Frame) + \\ - `anyframe` + \\ - [struct](https://ziglang.org/documentation/0.10.0/#struct) + \\ - [enum](https://ziglang.org/documentation/0.10.0/#enum) + \\ - [Enum Literals](https://ziglang.org/documentation/0.10.0/#Enum-Literals) + \\ - [union](https://ziglang.org/documentation/0.10.0/#union) \\For these types, `@Type` is not available: - \\ - [Functions](https://ziglang.org/documentation/0.10.0/#Functions) - \\ - BoundFn + \\ + \\ - [Functions](https://ziglang.org/documentation/0.10.0/#Functions) + \\ - BoundFn , .arguments = &.{ "comptime info: std.builtin.Type", @@ -1769,7 +2012,23 @@ pub const builtins = [_]Builtin{ .documentation = \\`@TypeOf` is a special builtin function that takes any (nonzero) number of expressions as parameters and returns the type of the result, using [Peer Type Resolution](https://ziglang.org/documentation/0.10.0/#Peer-Type-Resolution). \\ - \\The expressions are evaluated, however they are guaranteed to have no *runtime* side-effects:

{#code_begin|test|no_runtime_side_effects#} const std = @import("std"); const expect = std.testing.expect; test "no runtime side effects" { var data: i32 = 0; const T = @TypeOf(foo(i32, &data)); comptime try expect(T == i32); try expect(data == 0); } fn foo(comptime T: type, ptr: *T) T { ptr.* += 1; return ptr.*; }` + \\The expressions are evaluated, however they are guaranteed to have no + \\**runtime** side-effects: + \\ + \\```zig + \\const std = @import("std"); + \\const expect = std.testing.expect; + \\test "no runtime side effects" { + \\ var data: i32 = 0; + \\ const T = @TypeOf(foo(i32, &data)); + \\ comptime try expect(T == i32); + \\ try expect(data == 0); + \\} + \\fn foo(comptime T: type, ptr: *T) T { + \\ ptr.* += 1; + \\ return ptr.*; + \\} + \\``` , .arguments = &.{ "...", @@ -1803,3 +2062,5 @@ pub const builtins = [_]Builtin{ }, }, }; + +// DO NOT EDIT diff --git a/src/data/0.7.0.zig b/src/data/0.7.0.zig index 96547f2..5a91ae9 100644 --- a/src/data/0.7.0.zig +++ b/src/data/0.7.0.zig @@ -1,3 +1,8 @@ +//! DO NOT EDIT +//! If you want to update this file run: +//! `zig build gen -- --generate-version-data 0.7.0` (requires an internet connection) +//! GENERATED BY src/config_gen/config_gen.zig + const Builtin = struct { name: []const u8, signature: []const u8, @@ -11,8 +16,8 @@ pub const builtins = [_]Builtin{ .name = "@addWithOverflow", .signature = "@addWithOverflow(comptime T: type, a: T, b: T, result: *T) bool", .snippet = "@addWithOverflow(${1:comptime T: type}, ${2:a: T}, ${3:b: T}, ${4:result: *T})", - .documentation = - \\ Performs result.* = a + b. If overflow or underflow occurs, stores the overflowed bits in result and returns true. If no overflow or underflow occurs, returns false. + .documentation = + \\Performs `result.* = a + b`. If overflow or underflow occurs, stores the overflowed bits in `result` and returns `true`. If no overflow or underflow occurs, returns `false`. , .arguments = &.{ "comptime T: type", @@ -25,9 +30,10 @@ pub const builtins = [_]Builtin{ .name = "@alignCast", .signature = "@alignCast(comptime alignment: u29, ptr: anytype) anytype", .snippet = "@alignCast(${1:comptime alignment: u29}, ${2:ptr: anytype})", - .documentation = - \\ ptr can be *T, fn(), ?*T, ?fn(), or []T. It returns the same type as ptr except with the alignment adjusted to the new value. - \\A pointer alignment safety check is added to the generated code to make sure the pointer is aligned as promised. + .documentation = + \\`ptr` can be `*T`, `fn()`, `?*T`, `?fn()`, or `[]T`. It returns the same type as `ptr` except with the alignment adjusted to the new value. + \\ + \\A [pointer alignment safety check](https://ziglang.org/documentation/0.7.0/#Incorrect-Pointer-Alignment) is added to the generated code to make sure the pointer is aligned as promised. , .arguments = &.{ "comptime alignment: u29", @@ -38,15 +44,16 @@ pub const builtins = [_]Builtin{ .name = "@alignOf", .signature = "@alignOf(comptime T: type) comptime_int", .snippet = "@alignOf(${1:comptime T: type})", - .documentation = - \\ This function returns the number of bytes that this type should be aligned to for the current target to match the C ABI. When the child type of a pointer has this alignment, the alignment can be omitted from the type. + .documentation = + \\This function returns the number of bytes that this type should be aligned to for the current target to match the C ABI. When the child type of a pointer has this alignment, the alignment can be omitted from the type. + \\ \\```zig \\const expect = @import("std").testing.expect; \\comptime { \\ expect(*u32 == *align(@alignOf(u32)) u32); \\} \\``` - \\ The result is a target-specific compile time constant. It is guaranteed to be less than or equal to @sizeOf(T). + \\The result is a target-specific compile time constant. It is guaranteed to be less than or equal to [@sizeOf(T)](https://ziglang.org/documentation/0.7.0/#sizeOf). , .arguments = &.{ "comptime T: type", @@ -56,8 +63,8 @@ pub const builtins = [_]Builtin{ .name = "@as", .signature = "@as(comptime T: type, expression) T", .snippet = "@as(${1:comptime T: type}, ${2:expression})", - .documentation = - \\ Performs Type Coercion. This cast is allowed when the conversion is unambiguous and safe, and is the preferred way to convert between types, whenever possible. + .documentation = + \\Performs [Type Coercion](https://ziglang.org/documentation/0.7.0/#Type-Coercion). This cast is allowed when the conversion is unambiguous and safe, and is the preferred way to convert between types, whenever possible. , .arguments = &.{ "comptime T: type", @@ -67,16 +74,17 @@ pub const builtins = [_]Builtin{ .{ .name = "@asyncCall", .signature = "@asyncCall(frame_buffer: []align(@alignOf(@Frame(anyAsyncFunction))) u8, result_ptr, function_ptr, args: anytype) anyframe->T", - .snippet = "@asyncCall(${1:frame_buffer: []align(@alignOf(@Frame(anyAsyncFunction))) u8}, ${2:result_ptr}, ${3:function_ptr}, ${4:args: anytype})", - .documentation = - \\ @asyncCall performs an async call on a function pointer, which may or may not be an async function. - \\ The provided frame_buffer must be large enough to fit the entire function frame. This size can be determined with @frameSize. To provide a too-small buffer invokes safety-checked Undefined Behavior. - \\ result_ptr is optional (null may be provided). If provided, the function call will write its result directly to the result pointer, which will be available to read after await completes. Any result location provided to await will copy the result from result_ptr. - \\test.zig + .snippet = "@asyncCall(${1:frame_buffer: []align(@alignOf(@Frame(anyAsyncFunction)})", + .documentation = + \\`@asyncCall` performs an `async` call on a function pointer, which may or may not be an [async function](https://ziglang.org/documentation/0.7.0/#Async-Functions). + \\ + \\The provided `frame_buffer` must be large enough to fit the entire function frame. This size can be determined with [@frameSize](https://ziglang.org/documentation/0.7.0/#frameSize). To provide a too-small buffer invokes safety-checked [Undefined Behavior](https://ziglang.org/documentation/0.7.0/#Undefined-Behavior). + \\ + \\`result_ptr` is optional ([null](https://ziglang.org/documentation/0.7.0/#null) may be provided). If provided, the function call will write its result directly to the result pointer, which will be available to read after [await](https://ziglang.org/documentation/0.7.0/#Async-and-Await) completes. Any result location provided to `await` will copy the result from `result_ptr`. + \\ \\```zig \\const std = @import("std"); \\const expect = std.testing.expect; - \\ \\test "async fn pointer in a struct field" { \\ var data: i32 = 1; \\ const Foo = struct { @@ -89,34 +97,25 @@ pub const builtins = [_]Builtin{ \\ resume f; \\ expect(data == 4); \\} - \\ \\fn func(y: *i32) void { \\ defer y.* += 2; \\ y.* += 1; \\ suspend; \\} \\``` - \\```zig - \\$ zig test test.zig - \\1/1 test "async fn pointer in a struct field"... OK - \\All 1 tests passed. - \\ - \\``` , .arguments = &.{ - "frame_buffer: []align(@alignOf(@Frame(anyAsyncFunction))) u8", - "result_ptr", - "function_ptr", - "args: anytype", + "frame_buffer: []align(@alignOf(@Frame(anyAsyncFunction)", }, }, .{ .name = "@atomicLoad", .signature = "@atomicLoad(comptime T: type, ptr: *const T, comptime ordering: builtin.AtomicOrder) T", .snippet = "@atomicLoad(${1:comptime T: type}, ${2:ptr: *const T}, ${3:comptime ordering: builtin.AtomicOrder})", - .documentation = - \\ This builtin function atomically dereferences a pointer and returns the value. - \\ T must be a pointer, a bool, a float, an integer or an enum. + .documentation = + \\This builtin function atomically dereferences a pointer and returns the value. + \\ + \\`T` must be a pointer, a `bool`, a float, an integer or an enum. , .arguments = &.{ "comptime T: type", @@ -128,10 +127,22 @@ pub const builtins = [_]Builtin{ .name = "@atomicRmw", .signature = "@atomicRmw(comptime T: type, ptr: *T, comptime op: builtin.AtomicRmwOp, operand: T, comptime ordering: builtin.AtomicOrder) T", .snippet = "@atomicRmw(${1:comptime T: type}, ${2:ptr: *T}, ${3:comptime op: builtin.AtomicRmwOp}, ${4:operand: T}, ${5:comptime ordering: builtin.AtomicOrder})", - .documentation = - \\ This builtin function atomically modifies memory and then returns the previous value. - \\ T must be a pointer, a bool, a float, an integer or an enum. - \\ Supported operations: + .documentation = + \\This builtin function atomically modifies memory and then returns the previous value. + \\ + \\`T` must be a pointer, a `bool`, a float, an integer or an enum. + \\ + \\Supported operations: + \\ + \\ - `.Xchg` - stores the operand unmodified. Supports enums, integers and floats. + \\ - `.Add` - for integers, twos complement wraparound addition. Also supports [Floats](https://ziglang.org/documentation/0.7.0/#Floats). + \\ - `.Sub` - for integers, twos complement wraparound subtraction. Also supports [Floats](https://ziglang.org/documentation/0.7.0/#Floats). + \\ - `.And` - bitwise and + \\ - `.Nand` - bitwise nand + \\ - `.Or` - bitwise or + \\ - `.Xor` - bitwise xor + \\ - `.Max` - stores the operand if it is larger. Supports integers and floats. + \\ - `.Min` - stores the operand if it is smaller. Supports integers and floats. , .arguments = &.{ "comptime T: type", @@ -145,9 +156,10 @@ pub const builtins = [_]Builtin{ .name = "@atomicStore", .signature = "@atomicStore(comptime T: type, ptr: *T, value: T, comptime ordering: builtin.AtomicOrder) void", .snippet = "@atomicStore(${1:comptime T: type}, ${2:ptr: *T}, ${3:value: T}, ${4:comptime ordering: builtin.AtomicOrder})", - .documentation = - \\ This builtin function atomically stores a value. - \\ T must be a pointer, a bool, a float, an integer or an enum. + .documentation = + \\This builtin function atomically stores a value. + \\ + \\`T` must be a pointer, a `bool`, a float, an integer or an enum. , .arguments = &.{ "comptime T: type", @@ -160,11 +172,18 @@ pub const builtins = [_]Builtin{ .name = "@bitCast", .signature = "@bitCast(comptime DestType: type, value: anytype) DestType", .snippet = "@bitCast(${1:comptime DestType: type}, ${2:value: anytype})", - .documentation = - \\ Converts a value of one type to another type. - \\ Asserts that @sizeOf(@TypeOf(value)) == @sizeOf(DestType). - \\ Asserts that @typeInfo(DestType) != .Pointer. Use @ptrCast or @intToPtr if you need this. - \\ Can be used for these things for example: + .documentation = + \\Converts a value of one type to another type. + \\ + \\Asserts that `@sizeOf(@TypeOf(value)) == @sizeOf(DestType)`. + \\ + \\Asserts that `@typeInfo(DestType) != .Pointer`. Use `@ptrCast` or `@intToPtr` if you need this. + \\ + \\Can be used for these things for example: + \\ + \\ - Convert `f32` to `u32` bits + \\ - Convert `i32` to `u32` preserving twos complement + \\Works at compile-time if `value` is known at compile time. It's a compile error to bitcast a struct to a scalar type of the same size since structs have undefined layout. However if the struct is packed then it works. , .arguments = &.{ "comptime DestType: type", @@ -175,9 +194,10 @@ pub const builtins = [_]Builtin{ .name = "@bitOffsetOf", .signature = "@bitOffsetOf(comptime T: type, comptime field_name: []const u8) comptime_int", .snippet = "@bitOffsetOf(${1:comptime T: type}, ${2:comptime field_name: []const u8})", - .documentation = - \\ Returns the bit offset of a field relative to its containing struct. - \\ For non packed structs, this will always be divisible by 8. For packed structs, non-byte-aligned fields will share a byte offset, but they will have different bit offsets. + .documentation = + \\Returns the bit offset of a field relative to its containing struct. + \\ + \\For non [packed structs](https://ziglang.org/documentation/0.7.0/#packed-struct), this will always be divisible by `8`. For packed structs, non-byte-aligned fields will share a byte offset, but they will have different bit offsets. , .arguments = &.{ "comptime T: type", @@ -188,9 +208,10 @@ pub const builtins = [_]Builtin{ .name = "@boolToInt", .signature = "@boolToInt(value: bool) u1", .snippet = "@boolToInt(${1:value: bool})", - .documentation = - \\ Converts true to u1(1) and false to u1(0). - \\ If the value is known at compile-time, the return type is comptime_int instead of u1. + .documentation = + \\Converts `true` to `u1(1)` and `false` to `u1(0)`. + \\ + \\If the value is known at compile-time, the return type is `comptime_int` instead of `u1`. , .arguments = &.{ "value: bool", @@ -200,9 +221,10 @@ pub const builtins = [_]Builtin{ .name = "@bitSizeOf", .signature = "@bitSizeOf(comptime T: type) comptime_int", .snippet = "@bitSizeOf(${1:comptime T: type})", - .documentation = - \\ This function returns the number of bits it takes to store T in memory. The result is a target-specific compile time constant. - \\ This function measures the size at runtime. For types that are disallowed at runtime, such as comptime_int and type, the result is 0. + .documentation = + \\This function returns the number of bits it takes to store `T` in memory. The result is a target-specific compile time constant. + \\ + \\This function measures the size at runtime. For types that are disallowed at runtime, such as `comptime_int` and `type`, the result is `0`. , .arguments = &.{ "comptime T: type", @@ -212,9 +234,10 @@ pub const builtins = [_]Builtin{ .name = "@breakpoint", .signature = "@breakpoint()", .snippet = "@breakpoint()", - .documentation = - \\ This function inserts a platform-specific debug trap instruction which causes debuggers to break there. - \\ This function is only valid within function scope. + .documentation = + \\This function inserts a platform-specific debug trap instruction which causes debuggers to break there. + \\ + \\This function is only valid within function scope. , .arguments = &.{}, }, @@ -222,9 +245,10 @@ pub const builtins = [_]Builtin{ .name = "@mulAdd", .signature = "@mulAdd(comptime T: type, a: T, b: T, c: T) T", .snippet = "@mulAdd(${1:comptime T: type}, ${2:a: T}, ${3:b: T}, ${4:c: T})", - .documentation = - \\ Fused multiply add, similar to (a * b) + c, except only rounds once, and is thus more accurate. - \\ Supports Floats and Vectors of floats. + .documentation = + \\Fused multiply add, similar to `(a * b) + c`, except only rounds once, and is thus more accurate. + \\ + \\Supports Floats and Vectors of floats. , .arguments = &.{ "comptime T: type", @@ -237,11 +261,14 @@ pub const builtins = [_]Builtin{ .name = "@byteSwap", .signature = "@byteSwap(comptime T: type, operand: T) T", .snippet = "@byteSwap(${1:comptime T: type}, ${2:operand: T})", - .documentation = - \\T must be an integer type with bit count evenly divisible by 8. - \\operand may be an integer or vector. - \\ Swaps the byte order of the integer. This converts a big endian integer to a little endian integer, and converts a little endian integer to a big endian integer. - \\ Note that for the purposes of memory layout with respect to endianness, the integer type should be related to the number of bytes reported by @sizeOf bytes. This is demonstrated with u24. @sizeOf(u24) == 4, which means that a u24 stored in memory takes 4 bytes, and those 4 bytes are what are swapped on a little vs big endian system. On the other hand, if T is specified to be u24, then only 3 bytes are reversed. + .documentation = + \\`T` must be an integer type with bit count evenly divisible by 8. + \\ + \\`operand` may be an [integer](https://ziglang.org/documentation/0.7.0/#Integers) or [vector](https://ziglang.org/documentation/0.7.0/#Vectors). + \\ + \\Swaps the byte order of the integer. This converts a big endian integer to a little endian integer, and converts a little endian integer to a big endian integer. + \\ + \\Note that for the purposes of memory layout with respect to endianness, the integer type should be related to the number of bytes reported by [@sizeOf](https://ziglang.org/documentation/0.7.0/#sizeOf) bytes. This is demonstrated with `u24`. `@sizeOf(u24) == 4`, which means that a `u24` stored in memory takes 4 bytes, and those 4 bytes are what are swapped on a little vs big endian system. On the other hand, if `T` is specified to be `u24`, then only 3 bytes are reversed. , .arguments = &.{ "comptime T: type", @@ -252,10 +279,12 @@ pub const builtins = [_]Builtin{ .name = "@bitReverse", .signature = "@bitReverse(comptime T: type, integer: T) T", .snippet = "@bitReverse(${1:comptime T: type}, ${2:integer: T})", - .documentation = - \\T accepts any integer type. - \\ Reverses the bitpattern of an integer value, including the sign bit if applicable. - \\ For example 0b10110110 (u8 = 182, i8 = -74) becomes 0b01101101 (u8 = 109, i8 = 109). + .documentation = + \\`T` accepts any integer type. + \\ + \\Reverses the bitpattern of an integer value, including the sign bit if applicable. + \\ + \\For example 0b10110110 (`u8 = 182`, `i8 = -74`) becomes 0b01101101 (`u8 = 109`, `i8 = 109`). , .arguments = &.{ "comptime T: type", @@ -266,8 +295,8 @@ pub const builtins = [_]Builtin{ .name = "@byteOffsetOf", .signature = "@byteOffsetOf(comptime T: type, comptime field_name: []const u8) comptime_int", .snippet = "@byteOffsetOf(${1:comptime T: type}, ${2:comptime field_name: []const u8})", - .documentation = - \\ Returns the byte offset of a field relative to its containing struct. + .documentation = + \\Returns the byte offset of a field relative to its containing struct. , .arguments = &.{ "comptime T: type", @@ -278,61 +307,46 @@ pub const builtins = [_]Builtin{ .name = "@call", .signature = "@call(options: std.builtin.CallOptions, function: anytype, args: anytype) anytype", .snippet = "@call(${1:options: std.builtin.CallOptions}, ${2:function: anytype}, ${3:args: anytype})", - .documentation = - \\ Calls a function, in the same way that invoking an expression with parentheses does: - \\call.zig + .documentation = + \\Calls a function, in the same way that invoking an expression with parentheses does: + \\ \\```zig \\const expect = @import("std").testing.expect; - \\ \\test "noinline function call" { \\ expect(@call(.{}, add, .{3, 9}) == 12); \\} - \\ \\fn add(a: i32, b: i32) i32 { \\ return a + b; \\} \\``` - \\```zig - \\$ zig test call.zig - \\1/1 test "noinline function call"... OK - \\All 1 tests passed. + \\`@call` allows more flexibility than normal function call syntax does. The `CallOptions` struct is reproduced here: \\ - \\``` - \\ @call allows more flexibility than normal function call syntax does. The CallOptions struct is reproduced here: \\```zig \\pub const CallOptions = struct { \\ modifier: Modifier = .auto, \\ stack: ?[]align(std.Target.stack_align) u8 = null, - \\ \\ pub const Modifier = enum { \\ /// Equivalent to function call syntax. \\ auto, - \\ \\ /// Equivalent to async keyword used with function call syntax. \\ async_kw, - \\ \\ /// Prevents tail call optimization. This guarantees that the return \\ /// address will point to the callsite, as opposed to the callsite's \\ /// callsite. If the call is otherwise required to be tail-called \\ /// or inlined, a compile error is emitted instead. \\ never_tail, - \\ \\ /// Guarantees that the call will not be inlined. If the call is \\ /// otherwise required to be inlined, a compile error is emitted instead. \\ never_inline, - \\ \\ /// Asserts that the function call will not suspend. This allows a \\ /// non-async function to call an async function. \\ no_async, - \\ \\ /// Guarantees that the call will be generated with tail call optimization. \\ /// If this is not possible, a compile error is emitted instead. \\ always_tail, - \\ \\ /// Guarantees that the call will inlined at the callsite. \\ /// If this is not possible, a compile error is emitted instead. \\ always_inline, - \\ \\ /// Evaluates the call at compile-time. If the call cannot be completed at \\ /// compile-time, a compile error is emitted instead. \\ compile_time, @@ -350,17 +364,17 @@ pub const builtins = [_]Builtin{ .name = "@cDefine", .signature = "@cDefine(comptime name: []u8, value)", .snippet = "@cDefine(${1:comptime name: []u8}, ${2:value})", - .documentation = - \\ This function can only occur inside @cImport. - \\ This appends #define $name $value to the @cImport temporary buffer. - \\ To define without a value, like this: - \\```zig - \\#define _GNU_SOURCE - \\``` - \\ Use the void value, like this: - \\```zig - \\@cDefine("_GNU_SOURCE", {}) - \\``` + .documentation = + \\This function can only occur inside `@cImport`. + \\ + \\This appends + \\`#define $name $value`to the `@cImport` temporary buffer. + \\ + \\To define without a value, like this: + \\ + \\`#define _GNU_SOURCE`Use the void value, like this: + \\ + \\`@cDefine("_GNU_SOURCE", {})` , .arguments = &.{ "comptime name: []u8", @@ -371,11 +385,17 @@ pub const builtins = [_]Builtin{ .name = "@cImport", .signature = "@cImport(expression) type", .snippet = "@cImport(${1:expression})", - .documentation = - \\ This function parses C code and imports the functions, types, variables, and compatible macro definitions into a new empty struct type, and then returns that type. - \\ expression is interpreted at compile time. The builtin functions @cInclude, @cDefine, and @cUndef work within this expression, appending to a temporary buffer which is then parsed as C code. - \\ Usually you should only have one @cImport in your entire application, because it saves the compiler from invoking clang multiple times, and prevents inline functions from being duplicated. - \\ Reasons for having multiple @cImport expressions would be: + .documentation = + \\This function parses C code and imports the functions, types, variables, and compatible macro definitions into a new empty struct type, and then returns that type. + \\ + \\`expression` is interpreted at compile time. The builtin functions `@cInclude`, `@cDefine`, and `@cUndef` work within this expression, appending to a temporary buffer which is then parsed as C code. + \\ + \\Usually you should only have one `@cImport` in your entire application, because it saves the compiler from invoking clang multiple times, and prevents inline functions from being duplicated. + \\ + \\Reasons for having multiple `@cImport` expressions would be: + \\ + \\ - To avoid a symbol collision, for example if foo.h and bar.h both + \\`#define CONNECTION_COUNT` - To analyze the C code with different preprocessor defines , .arguments = &.{ "expression", @@ -385,9 +405,11 @@ pub const builtins = [_]Builtin{ .name = "@cInclude", .signature = "@cInclude(comptime path: []u8)", .snippet = "@cInclude(${1:comptime path: []u8})", - .documentation = - \\ This function can only occur inside @cImport. - \\ This appends #include <$path>\n to the c_import temporary buffer. + .documentation = + \\This function can only occur inside `@cImport`. + \\ + \\This appends + \\`#include <$path>\n`to the `c_import` temporary buffer. , .arguments = &.{ "comptime path: []u8", @@ -397,10 +419,12 @@ pub const builtins = [_]Builtin{ .name = "@clz", .signature = "@clz(comptime T: type, integer: T)", .snippet = "@clz(${1:comptime T: type}, ${2:integer: T})", - .documentation = - \\ This function counts the number of most-significant (leading in a big-Endian sense) zeroes in integer. - \\ If integer is known at comptime, the return type is comptime_int. Otherwise, the return type is an unsigned integer with the minimum number of bits that can represent the bit count of the integer type. - \\ If integer is zero, @clz returns the bit width of integer type T. + .documentation = + \\This function counts the number of most-significant (leading in a big-Endian sense) zeroes in `integer`. + \\ + \\If `integer` is known at [comptime](https://ziglang.org/documentation/0.7.0/#comptime), the return type is `comptime_int`. Otherwise, the return type is an unsigned integer with the minimum number of bits that can represent the bit count of the integer type. + \\ + \\If `integer` is zero, `@clz` returns the bit width of integer type `T`. , .arguments = &.{ "comptime T: type", @@ -411,8 +435,9 @@ pub const builtins = [_]Builtin{ .name = "@cmpxchgStrong", .signature = "@cmpxchgStrong(comptime T: type, ptr: *T, expected_value: T, new_value: T, success_order: AtomicOrder, fail_order: AtomicOrder) ?T", .snippet = "@cmpxchgStrong(${1:comptime T: type}, ${2:ptr: *T}, ${3:expected_value: T}, ${4:new_value: T}, ${5:success_order: AtomicOrder}, ${6:fail_order: AtomicOrder})", - .documentation = - \\ This function performs a strong atomic compare exchange operation. It's the equivalent of this code, except atomic: + .documentation = + \\This function performs a strong atomic compare exchange operation. It's the equivalent of this code, except atomic: + \\ \\```zig \\fn cmpxchgStrongButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_value: T) ?T { \\ const old_value = ptr.*; @@ -424,9 +449,11 @@ pub const builtins = [_]Builtin{ \\ } \\} \\``` - \\ If you are using cmpxchg in a loop, @cmpxchgWeak is the better choice, because it can be implemented more efficiently in machine instructions. - \\ T must be a pointer, a bool, a float, an integer or an enum. - \\@typeInfo(@TypeOf(ptr)).Pointer.alignment must be >= @sizeOf(T). + \\If you are using cmpxchg in a loop, [@cmpxchgWeak](https://ziglang.org/documentation/0.7.0/#cmpxchgWeak) is the better choice, because it can be implemented more efficiently in machine instructions. + \\ + \\`T` must be a pointer, a `bool`, a float, an integer or an enum. + \\ + \\`@typeInfo(@TypeOf(ptr)).Pointer.alignment` must be `>= @sizeOf(T).` , .arguments = &.{ "comptime T: type", @@ -441,8 +468,9 @@ pub const builtins = [_]Builtin{ .name = "@cmpxchgWeak", .signature = "@cmpxchgWeak(comptime T: type, ptr: *T, expected_value: T, new_value: T, success_order: AtomicOrder, fail_order: AtomicOrder) ?T", .snippet = "@cmpxchgWeak(${1:comptime T: type}, ${2:ptr: *T}, ${3:expected_value: T}, ${4:new_value: T}, ${5:success_order: AtomicOrder}, ${6:fail_order: AtomicOrder})", - .documentation = - \\ This function performs a weak atomic compare exchange operation. It's the equivalent of this code, except atomic: + .documentation = + \\This function performs a weak atomic compare exchange operation. It's the equivalent of this code, except atomic: + \\ \\```zig \\fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_value: T) ?T { \\ const old_value = ptr.*; @@ -454,9 +482,11 @@ pub const builtins = [_]Builtin{ \\ } \\} \\``` - \\ If you are using cmpxchg in a loop, the sporadic failure will be no problem, and cmpxchgWeak is the better choice, because it can be implemented more efficiently in machine instructions. However if you need a stronger guarantee, use @cmpxchgStrong. - \\ T must be a pointer, a bool, a float, an integer or an enum. - \\@typeInfo(@TypeOf(ptr)).Pointer.alignment must be >= @sizeOf(T). + \\If you are using cmpxchg in a loop, the sporadic failure will be no problem, and `cmpxchgWeak` is the better choice, because it can be implemented more efficiently in machine instructions. However if you need a stronger guarantee, use [@cmpxchgStrong](https://ziglang.org/documentation/0.7.0/#cmpxchgStrong). + \\ + \\`T` must be a pointer, a `bool`, a float, an integer or an enum. + \\ + \\`@typeInfo(@TypeOf(ptr)).Pointer.alignment` must be `>= @sizeOf(T).` , .arguments = &.{ "comptime T: type", @@ -471,9 +501,10 @@ pub const builtins = [_]Builtin{ .name = "@compileError", .signature = "@compileError(comptime msg: []u8)", .snippet = "@compileError(${1:comptime msg: []u8})", - .documentation = - \\ This function, when semantically analyzed, causes a compile error with the message msg. - \\ There are several ways that code avoids being semantically checked, such as using if or switch with compile time constants, and comptime functions. + .documentation = + \\This function, when semantically analyzed, causes a compile error with the message `msg`. + \\ + \\There are several ways that code avoids being semantically checked, such as using `if` or `switch` with compile time constants, and `comptime` functions. , .arguments = &.{ "comptime msg: []u8", @@ -483,71 +514,41 @@ pub const builtins = [_]Builtin{ .name = "@compileLog", .signature = "@compileLog(args: ...)", .snippet = "@compileLog(${1:args: ...})", - .documentation = - \\ This function prints the arguments passed to it at compile-time. - \\ To prevent accidentally leaving compile log statements in a codebase, a compilation error is added to the build, pointing to the compile log statement. This error prevents code from being generated, but does not otherwise interfere with analysis. - \\ This function can be used to do "printf debugging" on compile-time executing code. - \\test.zig + .documentation = + \\This function prints the arguments passed to it at compile-time. + \\ + \\To prevent accidentally leaving compile log statements in a codebase, a compilation error is added to the build, pointing to the compile log statement. This error prevents code from being generated, but does not otherwise interfere with analysis. + \\ + \\This function can be used to do "printf debugging" on compile-time executing code. + \\ \\```zig \\const print = @import("std").debug.print; - \\ \\const num1 = blk: { \\ var val1: i32 = 99; \\ @compileLog("comptime val1 = ", val1); \\ val1 = val1 + 1; \\ break :blk val1; \\}; - \\ \\test "main" { \\ @compileLog("comptime in main"); - \\ \\ print("Runtime in main, num1 = {}.\n", .{num1}); \\} \\``` - \\```zig - \\$ zig test test.zig - \\| *"comptime in main" - \\| *"comptime val1 = ", 99 - \\./docgen_tmp/test.zig:11:5: error: found compile log statement - \\ @compileLog("comptime in main"); - \\ ^ - \\./docgen_tmp/test.zig:1:35: note: referenced here - \\const print = @import("std").debug.print; - \\ ^ - \\./docgen_tmp/test.zig:13:5: note: referenced here - \\ print("Runtime in main, num1 = {}.\n", .{num1}); - \\ ^ - \\./docgen_tmp/test.zig:5:5: error: found compile log statement - \\ @compileLog("comptime val1 = ", val1); - \\ ^ - \\./docgen_tmp/test.zig:13:46: note: referenced here - \\ print("Runtime in main, num1 = {}.\n", .{num1}); - \\ ^ + \\will ouput: + \\ + \\If all `@compileLog` calls are removed or not encountered by analysis, the program compiles successfully and the generated executable prints: \\ - \\``` - \\ will ouput: - \\ If all @compileLog calls are removed or not encountered by analysis, the program compiles successfully and the generated executable prints: - \\test.zig \\```zig \\const print = @import("std").debug.print; - \\ \\const num1 = blk: { \\ var val1: i32 = 99; \\ val1 = val1 + 1; \\ break :blk val1; \\}; - \\ \\test "main" { \\ print("Runtime in main, num1 = {}.\n", .{num1}); \\} \\``` - \\```zig - \\$ zig test test.zig - \\1/1 test "main"... Runtime in main, num1 = 100. - \\OK - \\All 1 tests passed. - \\ - \\``` , .arguments = &.{ "args: ...", @@ -557,10 +558,12 @@ pub const builtins = [_]Builtin{ .name = "@ctz", .signature = "@ctz(comptime T: type, integer: T)", .snippet = "@ctz(${1:comptime T: type}, ${2:integer: T})", - .documentation = - \\ This function counts the number of least-significant (trailing in a big-Endian sense) zeroes in integer. - \\ If integer is known at comptime, the return type is comptime_int. Otherwise, the return type is an unsigned integer with the minimum number of bits that can represent the bit count of the integer type. - \\ If integer is zero, @ctz returns the bit width of integer type T. + .documentation = + \\This function counts the number of least-significant (trailing in a big-Endian sense) zeroes in `integer`. + \\ + \\If `integer` is known at [comptime](https://ziglang.org/documentation/0.7.0/#comptime), the return type is `comptime_int`. Otherwise, the return type is an unsigned integer with the minimum number of bits that can represent the bit count of the integer type. + \\ + \\If `integer` is zero, `@ctz` returns the bit width of integer type `T`. , .arguments = &.{ "comptime T: type", @@ -571,9 +574,11 @@ pub const builtins = [_]Builtin{ .name = "@cUndef", .signature = "@cUndef(comptime name: []u8)", .snippet = "@cUndef(${1:comptime name: []u8})", - .documentation = - \\ This function can only occur inside @cImport. - \\ This appends #undef $name to the @cImport temporary buffer. + .documentation = + \\This function can only occur inside `@cImport`. + \\ + \\This appends + \\`#undef $name`to the `@cImport` temporary buffer. , .arguments = &.{ "comptime name: []u8", @@ -583,8 +588,12 @@ pub const builtins = [_]Builtin{ .name = "@divExact", .signature = "@divExact(numerator: T, denominator: T) T", .snippet = "@divExact(${1:numerator: T}, ${2:denominator: T})", - .documentation = - \\ Exact division. Caller guarantees denominator != 0 and @divTrunc(numerator, denominator) * denominator == numerator. + .documentation = + \\Exact division. Caller guarantees `denominator != 0` and `@divTrunc(numerator, denominator) * denominator == numerator`. + \\ + \\ - `@divExact(6, 3) == 2` + \\ - `@divExact(a, b) * b == a` + \\For a function that returns a possible error code, use `@import("std").math.divExact`. , .arguments = &.{ "numerator: T", @@ -595,8 +604,12 @@ pub const builtins = [_]Builtin{ .name = "@divFloor", .signature = "@divFloor(numerator: T, denominator: T) T", .snippet = "@divFloor(${1:numerator: T}, ${2:denominator: T})", - .documentation = - \\ Floored division. Rounds toward negative infinity. For unsigned integers it is the same as numerator / denominator. Caller guarantees denominator != 0 and !(@typeInfo(T) == .Int and T.is_signed and numerator == std.math.minInt(T) and denominator == -1). + .documentation = + \\Floored division. Rounds toward negative infinity. For unsigned integers it is the same as `numerator / denominator`. Caller guarantees `denominator != 0` and `!(@typeInfo(T) == .Int and T.is_signed and numerator == std.math.minInt(T) and denominator == -1)`. + \\ + \\ - `@divFloor(-5, 3) == -2` + \\ - `(@divFloor(a, b) * b) + @mod(a, b) == a` + \\For a function that returns a possible error code, use `@import("std").math.divFloor`. , .arguments = &.{ "numerator: T", @@ -607,8 +620,12 @@ pub const builtins = [_]Builtin{ .name = "@divTrunc", .signature = "@divTrunc(numerator: T, denominator: T) T", .snippet = "@divTrunc(${1:numerator: T}, ${2:denominator: T})", - .documentation = - \\ Truncated division. Rounds toward zero. For unsigned integers it is the same as numerator / denominator. Caller guarantees denominator != 0 and !(@typeInfo(T) == .Int and T.is_signed and numerator == std.math.minInt(T) and denominator == -1). + .documentation = + \\Truncated division. Rounds toward zero. For unsigned integers it is the same as `numerator / denominator`. Caller guarantees `denominator != 0` and `!(@typeInfo(T) == .Int and T.is_signed and numerator == std.math.minInt(T) and denominator == -1)`. + \\ + \\ - `@divTrunc(-5, 3) == -1` + \\ - `(@divTrunc(a, b) * b) + @rem(a, b) == a` + \\For a function that returns a possible error code, use `@import("std").math.divTrunc`. , .arguments = &.{ "numerator: T", @@ -619,9 +636,10 @@ pub const builtins = [_]Builtin{ .name = "@embedFile", .signature = "@embedFile(comptime path: []const u8) *const [X:0]u8", .snippet = "@embedFile(${1:comptime path: []const u8})", - .documentation = - \\ This function returns a compile time constant pointer to null-terminated, fixed-size array with length equal to the byte count of the file given by path. The contents of the array are the contents of the file. This is equivalent to a string literal with the file contents. - \\ path is absolute or relative to the current file, just like @import. + .documentation = + \\This function returns a compile time constant pointer to null-terminated, fixed-size array with length equal to the byte count of the file given by `path`. The contents of the array are the contents of the file. This is equivalent to a [string literal](https://ziglang.org/documentation/0.7.0/#String-Literals-and-Character-Literals) with the file contents. + \\ + \\`path` is absolute or relative to the current file, just like `@import`. , .arguments = &.{ "comptime path: []const u8", @@ -631,9 +649,10 @@ pub const builtins = [_]Builtin{ .name = "@enumToInt", .signature = "@enumToInt(enum_or_tagged_union: anytype) anytype", .snippet = "@enumToInt(${1:enum_or_tagged_union: anytype})", - .documentation = - \\ Converts an enumeration value into its integer tag type. When a tagged union is passed, the tag value is used as the enumeration value. - \\ If there is only one possible enum value, the resut is a comptime_int known at comptime. + .documentation = + \\Converts an enumeration value into its integer tag type. When a tagged union is passed, the tag value is used as the enumeration value. + \\ + \\If there is only one possible enum value, the resut is a `comptime_int` known at [comptime](https://ziglang.org/documentation/0.7.0/#comptime). , .arguments = &.{ "enum_or_tagged_union: anytype", @@ -643,9 +662,10 @@ pub const builtins = [_]Builtin{ .name = "@errorName", .signature = "@errorName(err: anyerror) []const u8", .snippet = "@errorName(${1:err: anyerror})", - .documentation = - \\ This function returns the string representation of an error. The string representation of error.OutOfMem is "OutOfMem". - \\ If there are no calls to @errorName in an entire application, or all calls have a compile-time known value for err, then no error name table will be generated. + .documentation = + \\This function returns the string representation of an error. The string representation of `error.OutOfMem` is `"OutOfMem"`. + \\ + \\If there are no calls to `@errorName` in an entire application, or all calls have a compile-time known value for `err`, then no error name table will be generated. , .arguments = &.{ "err: anyerror", @@ -655,8 +675,8 @@ pub const builtins = [_]Builtin{ .name = "@errorReturnTrace", .signature = "@errorReturnTrace() ?*builtin.StackTrace", .snippet = "@errorReturnTrace()", - .documentation = - \\ If the binary is built with error return tracing, and this function is invoked in a function that calls a function with an error or error union return type, returns a stack trace object. Otherwise returns `null`. + .documentation = + \\If the binary is built with error return tracing, and this function is invoked in a function that calls a function with an error or error union return type, returns a stack trace object. Otherwise returns `null`. , .arguments = &.{}, }, @@ -664,8 +684,15 @@ pub const builtins = [_]Builtin{ .name = "@errorToInt", .signature = "@errorToInt(err: anytype) std.meta.IntType(false, @sizeOf(anyerror) * 8)", .snippet = "@errorToInt(${1:err: anytype})", - .documentation = - \\ Supports the following types: + .documentation = + \\Supports the following types: + \\ + \\ - [The Global Error Set](https://ziglang.org/documentation/0.7.0/#The-Global-Error-Set) + \\ - [Error Set Type](https://ziglang.org/documentation/0.7.0/#Error-Set-Type) + \\ - [Error Union Type](https://ziglang.org/documentation/0.7.0/#Error-Union-Type) + \\Converts an error to the integer representation of an error. + \\ + \\It is generally recommended to avoid this cast, as the integer representation of an error is not stable across source code changes. , .arguments = &.{ "err: anytype", @@ -675,8 +702,8 @@ pub const builtins = [_]Builtin{ .name = "@errSetCast", .signature = "@errSetCast(comptime T: DestType, value: anytype) DestType", .snippet = "@errSetCast(${1:comptime T: DestType}, ${2:value: anytype})", - .documentation = - \\ Converts an error value from one error set to another error set. Attempting to convert an error which is not in the destination error set results in safety-protected Undefined Behavior. + .documentation = + \\Converts an error value from one error set to another error set. Attempting to convert an error which is not in the destination error set results in safety-protected [Undefined Behavior](https://ziglang.org/documentation/0.7.0/#Undefined-Behavior). , .arguments = &.{ "comptime T: DestType", @@ -687,40 +714,26 @@ pub const builtins = [_]Builtin{ .name = "@export", .signature = "@export(target: anytype, comptime options: std.builtin.ExportOptions) void", .snippet = "@export(${1:target: anytype}, ${2:comptime options: std.builtin.ExportOptions})", - .documentation = - \\ Creates a symbol in the output object file. - \\ This function can be called from a comptime block to conditionally export symbols. When target is a function with the C calling convention and options.linkage is Strong, this is equivalent to the export keyword used on a function: - \\test.zig + .documentation = + \\Creates a symbol in the output object file. + \\ + \\This function can be called from a [comptime](https://ziglang.org/documentation/0.7.0/#comptime) block to conditionally export symbols. When `target` is a function with the C calling convention and `options.linkage` is `Strong`, this is equivalent to the `export` keyword used on a function: + \\ \\```zig \\comptime { \\ @export(internalName, .{ .name = "foo", .linkage = .Strong }); \\} - \\ \\fn internalName() callconv(.C) void {} \\``` - \\```zig - \\$ zig build-obj test.zig - \\``` \\This is equivalent to: - \\test.zig - \\```zig - \\export fn foo() void {} - \\``` - \\```zig - \\$ zig build-obj test.zig - \\``` - \\Note that even when using export, @"foo" syntax can be used to choose any string for the symbol name: - \\test.zig - \\```zig - \\export fn @"A function name that is a complete sentence."() void {} - \\``` - \\```zig - \\$ zig build-obj test.zig - \\``` - \\ When looking at the resulting object, you can see the symbol is used verbatim: - \\```zig - \\00000000000001f0 T A function name that is a complete sentence. - \\``` + \\ + \\`export fn foo() void {}` + \\Note that even when using `export`, `@"foo"` syntax can be used to choose any string for the symbol name: + \\ + \\`export fn @"A function name that is a complete sentence."() void {}` + \\When looking at the resulting object, you can see the symbol is used verbatim: + \\ + \\`00000000000001f0 T A function name that is a complete sentence.` , .arguments = &.{ "target: anytype", @@ -731,9 +744,10 @@ pub const builtins = [_]Builtin{ .name = "@fence", .signature = "@fence(order: AtomicOrder)", .snippet = "@fence(${1:order: AtomicOrder})", - .documentation = - \\ The fence function is used to introduce happens-before edges between operations. - \\ AtomicOrder can be found with @import("builtin").AtomicOrder. + .documentation = + \\The `fence` function is used to introduce happens-before edges between operations. + \\ + \\`AtomicOrder` can be found with `@import("builtin").AtomicOrder`. , .arguments = &.{ "order: AtomicOrder", @@ -743,34 +757,24 @@ pub const builtins = [_]Builtin{ .name = "@field", .signature = "@field(lhs: anytype, comptime field_name: []const u8) (field)", .snippet = "@field(${1:lhs: anytype}, ${2:comptime field_name: []const u8})", - .documentation = - \\Performs field access by a compile-time string. - \\test.zig + .documentation = + \\Performs field access by a compile-time string. + \\ \\```zig \\const std = @import("std"); - \\ \\const Point = struct { \\ x: u32, \\ y: u32 \\}; - \\ \\test "field access by string" { \\ const expect = std.testing.expect; \\ var p = Point {.x = 0, .y = 0}; - \\ \\ @field(p, "x") = 4; \\ @field(p, "y") = @field(p, "x") + 1; - \\ \\ expect(@field(p, "x") == 4); \\ expect(@field(p, "y") == 5); \\} \\``` - \\```zig - \\$ zig test test.zig - \\1/1 test "field access by string"... OK - \\All 1 tests passed. - \\ - \\``` , .arguments = &.{ "lhs: anytype", @@ -781,8 +785,8 @@ pub const builtins = [_]Builtin{ .name = "@fieldParentPtr", .signature = "@fieldParentPtr(comptime ParentType: type, comptime field_name: []const u8, field_ptr: *T) *ParentType", .snippet = "@fieldParentPtr(${1:comptime ParentType: type}, ${2:comptime field_name: []const u8}, ${3:field_ptr: *T})", - .documentation = - \\ Given a pointer to a field, returns the base pointer of a struct. + .documentation = + \\Given a pointer to a field, returns the base pointer of a struct. , .arguments = &.{ "comptime ParentType: type", @@ -794,8 +798,8 @@ pub const builtins = [_]Builtin{ .name = "@floatCast", .signature = "@floatCast(comptime DestType: type, value: anytype) DestType", .snippet = "@floatCast(${1:comptime DestType: type}, ${2:value: anytype})", - .documentation = - \\ Convert from one float type to another. This cast is safe, but may cause the numeric value to lose precision. + .documentation = + \\Convert from one float type to another. This cast is safe, but may cause the numeric value to lose precision. , .arguments = &.{ "comptime DestType: type", @@ -806,9 +810,10 @@ pub const builtins = [_]Builtin{ .name = "@floatToInt", .signature = "@floatToInt(comptime DestType: type, float: anytype) DestType", .snippet = "@floatToInt(${1:comptime DestType: type}, ${2:float: anytype})", - .documentation = - \\ Converts the integer part of a floating point number to the destination type. - \\ If the integer part of the floating point number cannot fit in the destination type, it invokes safety-checked Undefined Behavior. + .documentation = + \\Converts the integer part of a floating point number to the destination type. + \\ + \\If the integer part of the floating point number cannot fit in the destination type, it invokes safety-checked [Undefined Behavior](https://ziglang.org/documentation/0.7.0/#Undefined-Behavior). , .arguments = &.{ "comptime DestType: type", @@ -819,9 +824,10 @@ pub const builtins = [_]Builtin{ .name = "@frame", .signature = "@frame() *@Frame(func)", .snippet = "@frame()", - .documentation = - \\ This function returns a pointer to the frame for a given function. This type can be coerced to anyframe->T and to anyframe, where T is the return type of the function in scope. - \\ This function does not mark a suspension point, but it does cause the function in scope to become an async function. + .documentation = + \\This function returns a pointer to the frame for a given function. This type can be [coerced](https://ziglang.org/documentation/0.7.0/#Type-Coercion) to `anyframe->T` and to `anyframe`, where `T` is the return type of the function in scope. + \\ + \\This function does not mark a suspension point, but it does cause the function in scope to become an [async function](https://ziglang.org/documentation/0.7.0/#Async-Functions). , .arguments = &.{}, }, @@ -829,28 +835,21 @@ pub const builtins = [_]Builtin{ .name = "@Frame", .signature = "@Frame(func: anytype) type", .snippet = "@Frame(${1:func: anytype})", - .documentation = - \\ This function returns the frame type of a function. This works for Async Functions as well as any function without a specific calling convention. - \\ This type is suitable to be used as the return type of async which allows one to, for example, heap-allocate an async function frame: - \\test.zig + .documentation = + \\This function returns the frame type of a function. This works for [Async Functions](https://ziglang.org/documentation/0.7.0/#Async-Functions) as well as any function without a specific calling convention. + \\ + \\This type is suitable to be used as the return type of [async](https://ziglang.org/documentation/0.7.0/#Async-and-Await) which allows one to, for example, heap-allocate an async function frame: + \\ \\```zig \\const std = @import("std"); - \\ \\test "heap allocated frame" { \\ const frame = try std.heap.page_allocator.create(@Frame(func)); \\ frame.* = async func(); \\} - \\ \\fn func() void { \\ suspend; \\} \\``` - \\```zig - \\$ zig test test.zig - \\1/1 test "heap allocated frame"... OK - \\All 1 tests passed. - \\ - \\``` , .arguments = &.{ "func: anytype", @@ -860,10 +859,12 @@ pub const builtins = [_]Builtin{ .name = "@frameAddress", .signature = "@frameAddress() usize", .snippet = "@frameAddress()", - .documentation = - \\ This function returns the base pointer of the current stack frame. - \\ The implications of this are target specific and not consistent across all platforms. The frame address may not be available in release mode due to aggressive optimizations. - \\ This function is only valid within function scope. + .documentation = + \\This function returns the base pointer of the current stack frame. + \\ + \\The implications of this are target specific and not consistent across all platforms. The frame address may not be available in release mode due to aggressive optimizations. + \\ + \\This function is only valid within function scope. , .arguments = &.{}, }, @@ -871,9 +872,10 @@ pub const builtins = [_]Builtin{ .name = "@frameSize", .signature = "@frameSize() usize", .snippet = "@frameSize()", - .documentation = - \\ This is the same as @sizeOf(@Frame(func)), where func may be runtime-known. - \\ This function is typically used in conjunction with @asyncCall. + .documentation = + \\This is the same as `@sizeOf(@Frame(func))`, where `func` may be runtime-known. + \\ + \\This function is typically used in conjunction with [@asyncCall](https://ziglang.org/documentation/0.7.0/#asyncCall). , .arguments = &.{}, }, @@ -881,39 +883,28 @@ pub const builtins = [_]Builtin{ .name = "@hasDecl", .signature = "@hasDecl(comptime Container: type, comptime name: []const u8) bool", .snippet = "@hasDecl(${1:comptime Container: type}, ${2:comptime name: []const u8})", - .documentation = - \\ Returns whether or not a struct, enum, or union has a declaration matching name. - \\test.zig + .documentation = + \\Returns whether or not a [struct](https://ziglang.org/documentation/0.7.0/#struct), [enum](https://ziglang.org/documentation/0.7.0/#enum), or [union](https://ziglang.org/documentation/0.7.0/#union) has a declaration matching `name`. + \\ \\```zig \\const std = @import("std"); \\const expect = std.testing.expect; - \\ \\const Foo = struct { \\ nope: i32, - \\ \\ pub var blah = "xxx"; \\ const hi = 1; \\}; - \\ \\test "@hasDecl" { \\ expect(@hasDecl(Foo, "blah")); - \\ \\ // Even though `hi` is private, @hasDecl returns true because this test is \\ // in the same file scope as Foo. It would return false if Foo was declared \\ // in a different file. \\ expect(@hasDecl(Foo, "hi")); - \\ \\ // @hasDecl is for declarations; not fields. \\ expect(!@hasDecl(Foo, "nope")); \\ expect(!@hasDecl(Foo, "nope1234")); \\} \\``` - \\```zig - \\$ zig test test.zig - \\1/1 test "@hasDecl"... OK - \\All 1 tests passed. - \\ - \\``` , .arguments = &.{ "comptime Container: type", @@ -924,10 +915,12 @@ pub const builtins = [_]Builtin{ .name = "@hasField", .signature = "@hasField(comptime Container: type, comptime name: []const u8) bool", .snippet = "@hasField(${1:comptime Container: type}, ${2:comptime name: []const u8})", - .documentation = + .documentation = \\Returns whether the field name of a struct, union, or enum exists. - \\ The result is a compile time constant. - \\ It does not include functions, variables, or constants. + \\ + \\The result is a compile time constant. + \\ + \\It does not include functions, variables, or constants. , .arguments = &.{ "comptime Container: type", @@ -938,12 +931,20 @@ pub const builtins = [_]Builtin{ .name = "@import", .signature = "@import(comptime path: []u8) type", .snippet = "@import(${1:comptime path: []u8})", - .documentation = - \\ This function finds a zig file corresponding to path and adds it to the build, if it is not already added. - \\ Zig source files are implicitly structs, with a name equal to the file's basename with the extension truncated. @import returns the struct type corresponding to the file. - \\ Declarations which have the pub keyword may be referenced from a different source file than the one they are declared in. - \\ path can be a relative path or it can be the name of a package. If it is a relative path, it is relative to the file that contains the @import function call. - \\ The following packages are always available: + .documentation = + \\This function finds a zig file corresponding to `path` and adds it to the build, if it is not already added. + \\ + \\Zig source files are implicitly structs, with a name equal to the file's basename with the extension truncated. `@import` returns the struct type corresponding to the file. + \\ + \\Declarations which have the `pub` keyword may be referenced from a different source file than the one they are declared in. + \\ + \\`path` can be a relative path or it can be the name of a package. If it is a relative path, it is relative to the file that contains the `@import` function call. + \\ + \\The following packages are always available: + \\ + \\ - `@import("std")` - Zig Standard Library + \\ - `@import("builtin")` - Compiler-provided types and variables. The command + \\`zig builtin`outputs the source to stdout for reference. , .arguments = &.{ "comptime path: []u8", @@ -953,9 +954,10 @@ pub const builtins = [_]Builtin{ .name = "@intCast", .signature = "@intCast(comptime DestType: type, int: anytype) DestType", .snippet = "@intCast(${1:comptime DestType: type}, ${2:int: anytype})", - .documentation = - \\ Converts an integer to another integer while keeping the same numerical value. Attempting to convert a number which is out of range of the destination type results in safety-protected Undefined Behavior. - \\ If T is comptime_int, then this is semantically equivalent to Type Coercion. + .documentation = + \\Converts an integer to another integer while keeping the same numerical value. Attempting to convert a number which is out of range of the destination type results in safety-protected [Undefined Behavior](https://ziglang.org/documentation/0.7.0/#Undefined-Behavior). + \\ + \\If `T` is `comptime_int`, then this is semantically equivalent to [Type Coercion](https://ziglang.org/documentation/0.7.0/#Type-Coercion). , .arguments = &.{ "comptime DestType: type", @@ -966,9 +968,10 @@ pub const builtins = [_]Builtin{ .name = "@intToEnum", .signature = "@intToEnum(comptime DestType: type, int_value: @TagType(DestType)) DestType", .snippet = "@intToEnum(${1:comptime DestType: type}, ${2:int_value: @TagType(DestType)})", - .documentation = - \\ Converts an integer into an enum value. - \\ Attempting to convert an integer which represents no value in the chosen enum type invokes safety-checked Undefined Behavior. + .documentation = + \\Converts an integer into an [enum](https://ziglang.org/documentation/0.7.0/#enum) value. + \\ + \\Attempting to convert an integer which represents no value in the chosen enum type invokes safety-checked [Undefined Behavior](https://ziglang.org/documentation/0.7.0/#Undefined-Behavior). , .arguments = &.{ "comptime DestType: type", @@ -978,22 +981,24 @@ pub const builtins = [_]Builtin{ .{ .name = "@intToError", .signature = "@intToError(value: std.meta.IntType(false, @sizeOf(anyerror) * 8)) anyerror", - .snippet = "@intToError(${1:value: std.meta.IntType(false, @sizeOf(anyerror) * 8)})", - .documentation = - \\ Converts from the integer representation of an error into The Global Error Set type. - \\ It is generally recommended to avoid this cast, as the integer representation of an error is not stable across source code changes. - \\ Attempting to convert an integer that does not correspond to any error results in safety-protected Undefined Behavior. + .snippet = "@intToError(${1:value: std.meta.IntType(false, @sizeOf(anyerror) * 8})", + .documentation = + \\Converts from the integer representation of an error into [The Global Error Set](https://ziglang.org/documentation/0.7.0/#The-Global-Error-Set) type. + \\ + \\It is generally recommended to avoid this cast, as the integer representation of an error is not stable across source code changes. + \\ + \\Attempting to convert an integer that does not correspond to any error results in safety-protected [Undefined Behavior](https://ziglang.org/documentation/0.7.0/#Undefined-Behavior). , .arguments = &.{ - "value: std.meta.IntType(false, @sizeOf(anyerror) * 8)", + "value: std.meta.IntType(false, @sizeOf(anyerror) * 8", }, }, .{ .name = "@intToFloat", .signature = "@intToFloat(comptime DestType: type, int: anytype) DestType", .snippet = "@intToFloat(${1:comptime DestType: type}, ${2:int: anytype})", - .documentation = - \\ Converts an integer to the closest floating point representation. To convert the other way, use @floatToInt. This cast is always safe. + .documentation = + \\Converts an integer to the closest floating point representation. To convert the other way, use [@floatToInt](https://ziglang.org/documentation/0.7.0/#floatToInt). This cast is always safe. , .arguments = &.{ "comptime DestType: type", @@ -1004,9 +1009,10 @@ pub const builtins = [_]Builtin{ .name = "@intToPtr", .signature = "@intToPtr(comptime DestType: type, address: usize) DestType", .snippet = "@intToPtr(${1:comptime DestType: type}, ${2:address: usize})", - .documentation = - \\ Converts an integer to a pointer. To convert the other way, use @ptrToInt. - \\ If the destination pointer type does not allow address zero and address is zero, this invokes safety-checked Undefined Behavior. + .documentation = + \\Converts an integer to a [pointer](https://ziglang.org/documentation/0.7.0/#Pointers). To convert the other way, use [@ptrToInt](https://ziglang.org/documentation/0.7.0/#ptrToInt). + \\ + \\If the destination pointer type does not allow address zero and `address` is zero, this invokes safety-checked [Undefined Behavior](https://ziglang.org/documentation/0.7.0/#Undefined-Behavior). , .arguments = &.{ "comptime DestType: type", @@ -1017,14 +1023,16 @@ pub const builtins = [_]Builtin{ .name = "@memcpy", .signature = "@memcpy(noalias dest: [*]u8, noalias source: [*]const u8, byte_count: usize)", .snippet = "@memcpy(${1:noalias dest: [*]u8}, ${2:noalias source: [*]const u8}, ${3:byte_count: usize})", - .documentation = - \\ This function copies bytes from one region of memory to another. dest and source are both pointers and must not overlap. - \\ This function is a low level intrinsic with no safety mechanisms. Most code should not use this function, instead using something like this: - \\```zig - \\for (source[0..byte_count]) |b, i| dest[i] = b; - \\``` - \\ The optimizer is intelligent enough to turn the above snippet into a memcpy. + .documentation = + \\This function copies bytes from one region of memory to another. `dest` and `source` are both pointers and must not overlap. + \\ + \\This function is a low level intrinsic with no safety mechanisms. Most code should not use this function, instead using something like this: + \\ + \\`for (source[0..byte_count]) |b, i| dest[i] = b;` + \\The optimizer is intelligent enough to turn the above snippet into a memcpy. + \\ \\There is also a standard library function for this: + \\ \\```zig \\const mem = @import("std").mem; \\mem.copy(u8, dest[0..byte_count], source[0..byte_count]); @@ -1040,14 +1048,16 @@ pub const builtins = [_]Builtin{ .name = "@memset", .signature = "@memset(dest: [*]u8, c: u8, byte_count: usize)", .snippet = "@memset(${1:dest: [*]u8}, ${2:c: u8}, ${3:byte_count: usize})", - .documentation = - \\ This function sets a region of memory to c. dest is a pointer. - \\ This function is a low level intrinsic with no safety mechanisms. Most code should not use this function, instead using something like this: - \\```zig - \\for (dest[0..byte_count]) |*b| b.* = c; - \\``` - \\ The optimizer is intelligent enough to turn the above snippet into a memset. + .documentation = + \\This function sets a region of memory to `c`. `dest` is a pointer. + \\ + \\This function is a low level intrinsic with no safety mechanisms. Most code should not use this function, instead using something like this: + \\ + \\`for (dest[0..byte_count]) |*b| b.* = c;` + \\The optimizer is intelligent enough to turn the above snippet into a memset. + \\ \\There is also a standard library function for this: + \\ \\```zig \\const mem = @import("std").mem; \\mem.set(u8, dest, c); @@ -1063,9 +1073,10 @@ pub const builtins = [_]Builtin{ .name = "@wasmMemorySize", .signature = "@wasmMemorySize(index: u32) u32", .snippet = "@wasmMemorySize(${1:index: u32})", - .documentation = - \\ This function returns the size of the Wasm memory identified by index as an unsigned value in units of Wasm pages. Note that each Wasm page is 64KB in size. - \\ This function is a low level intrinsic with no safety mechanisms usually useful for allocator designers targeting Wasm. So unless you are writing a new allocator from scratch, you should use something like @import("std").heap.WasmPageAllocator. + .documentation = + \\This function returns the size of the Wasm memory identified by `index` as an unsigned value in units of Wasm pages. Note that each Wasm page is 64KB in size. + \\ + \\This function is a low level intrinsic with no safety mechanisms usually useful for allocator designers targeting Wasm. So unless you are writing a new allocator from scratch, you should use something like `@import("std").heap.WasmPageAllocator`. , .arguments = &.{ "index: u32", @@ -1075,29 +1086,22 @@ pub const builtins = [_]Builtin{ .name = "@wasmMemoryGrow", .signature = "@wasmMemoryGrow(index: u32, delta: u32) i32", .snippet = "@wasmMemoryGrow(${1:index: u32}, ${2:delta: u32})", - .documentation = - \\ This function increases the size of the Wasm memory identified by index by delta in units of unsigned number of Wasm pages. Note that each Wasm page is 64KB in size. On success, returns previous memory size; on failure, if the allocation fails, returns -1. - \\ This function is a low level intrinsic with no safety mechanisms usually useful for allocator designers targeting Wasm. So unless you are writing a new allocator from scratch, you should use something like @import("std").heap.WasmPageAllocator. - \\test.zig + .documentation = + \\This function increases the size of the Wasm memory identified by `index` by `delta` in units of unsigned number of Wasm pages. Note that each Wasm page is 64KB in size. On success, returns previous memory size; on failure, if the allocation fails, returns -1. + \\ + \\This function is a low level intrinsic with no safety mechanisms usually useful for allocator designers targeting Wasm. So unless you are writing a new allocator from scratch, you should use something like `@import("std").heap.WasmPageAllocator`. + \\ \\```zig \\const std = @import("std"); \\const builtin = @import("builtin"); \\const expect = std.testing.expect; - \\ \\test "@wasmMemoryGrow" { \\ if (builtin.arch != .wasm32) return error.SkipZigTest; - \\ \\ var prev = @wasmMemorySize(0); \\ expect(prev == @wasmMemoryGrow(0, 1)); \\ expect(prev + 1 == @wasmMemorySize(0)); \\} \\``` - \\```zig - \\$ zig test test.zig - \\1/1 test "@wasmMemoryGrow"... SKIP - \\0 passed; 1 skipped. - \\ - \\``` , .arguments = &.{ "index: u32", @@ -1108,8 +1112,12 @@ pub const builtins = [_]Builtin{ .name = "@mod", .signature = "@mod(numerator: T, denominator: T) T", .snippet = "@mod(${1:numerator: T}, ${2:denominator: T})", - .documentation = - \\ Modulus division. For unsigned integers this is the same as numerator % denominator. Caller guarantees denominator > 0. + .documentation = + \\Modulus division. For unsigned integers this is the same as `numerator % denominator`. Caller guarantees `denominator > 0`. + \\ + \\ - `@mod(-5, 3) == 1` + \\ - `(@divFloor(a, b) * b) + @mod(a, b) == a` + \\For a function that returns an error code, see `@import("std").math.mod`. , .arguments = &.{ "numerator: T", @@ -1120,8 +1128,8 @@ pub const builtins = [_]Builtin{ .name = "@mulWithOverflow", .signature = "@mulWithOverflow(comptime T: type, a: T, b: T, result: *T) bool", .snippet = "@mulWithOverflow(${1:comptime T: type}, ${2:a: T}, ${3:b: T}, ${4:result: *T})", - .documentation = - \\ Performs result.* = a * b. If overflow or underflow occurs, stores the overflowed bits in result and returns true. If no overflow or underflow occurs, returns false. + .documentation = + \\Performs `result.* = a * b`. If overflow or underflow occurs, stores the overflowed bits in `result` and returns `true`. If no overflow or underflow occurs, returns `false`. , .arguments = &.{ "comptime T: type", @@ -1134,9 +1142,13 @@ pub const builtins = [_]Builtin{ .name = "@panic", .signature = "@panic(message: []const u8) noreturn", .snippet = "@panic(${1:message: []const u8})", - .documentation = - \\ Invokes the panic handler function. By default the panic handler function calls the public panic function exposed in the root source file, or if there is not one specified, the std.builtin.default_panic function from std/builtin.zig. - \\Generally it is better to use @import("std").debug.panic. However, @panic can be useful for 2 scenarios: + .documentation = + \\Invokes the panic handler function. By default the panic handler function calls the public `panic` function exposed in the root source file, or if there is not one specified, the `std.builtin.default_panic` function from `std/builtin.zig`. + \\ + \\Generally it is better to use `@import("std").debug.panic`. However, `@panic` can be useful for 2 scenarios: + \\ + \\ - From library code, calling the programmer's panic function if they exposed one in the root source file. + \\ - When mixing C and Zig code, calling the canonical panic implementation across multiple .o files. , .arguments = &.{ "message: []const u8", @@ -1146,9 +1158,10 @@ pub const builtins = [_]Builtin{ .name = "@popCount", .signature = "@popCount(comptime T: type, integer: T)", .snippet = "@popCount(${1:comptime T: type}, ${2:integer: T})", - .documentation = + .documentation = \\Counts the number of bits set in an integer. - \\ If integer is known at comptime, the return type is comptime_int. Otherwise, the return type is an unsigned integer with the minimum number of bits that can represent the bit count of the integer type. + \\ + \\If `integer` is known at [comptime](https://ziglang.org/documentation/0.7.0/#comptime), the return type is `comptime_int`. Otherwise, the return type is an unsigned integer with the minimum number of bits that can represent the bit count of the integer type. , .arguments = &.{ "comptime T: type", @@ -1159,9 +1172,10 @@ pub const builtins = [_]Builtin{ .name = "@ptrCast", .signature = "@ptrCast(comptime DestType: type, value: anytype) DestType", .snippet = "@ptrCast(${1:comptime DestType: type}, ${2:value: anytype})", - .documentation = - \\ Converts a pointer of one type to a pointer of another type. - \\ Optional Pointers are allowed. Casting an optional pointer which is null to a non-optional pointer invokes safety-checked Undefined Behavior. + .documentation = + \\Converts a pointer of one type to a pointer of another type. + \\ + \\[Optional Pointers](https://ziglang.org/documentation/0.7.0/#Optional-Pointers) are allowed. Casting an optional pointer which is [null](https://ziglang.org/documentation/0.7.0/#null) to a non-optional pointer invokes safety-checked [Undefined Behavior](https://ziglang.org/documentation/0.7.0/#Undefined-Behavior). , .arguments = &.{ "comptime DestType: type", @@ -1172,8 +1186,14 @@ pub const builtins = [_]Builtin{ .name = "@ptrToInt", .signature = "@ptrToInt(value: anytype) usize", .snippet = "@ptrToInt(${1:value: anytype})", - .documentation = - \\ Converts value to a usize which is the address of the pointer. value can be one of these types: + .documentation = + \\Converts `value` to a `usize` which is the address of the pointer. `value` can be one of these types: + \\ + \\ - `*T` + \\ - `?*T` + \\ - `fn()` + \\ - `?fn()` + \\To convert the other way, use [@intToPtr](https://ziglang.org/documentation/0.7.0/#intToPtr) , .arguments = &.{ "value: anytype", @@ -1183,8 +1203,12 @@ pub const builtins = [_]Builtin{ .name = "@rem", .signature = "@rem(numerator: T, denominator: T) T", .snippet = "@rem(${1:numerator: T}, ${2:denominator: T})", - .documentation = - \\ Remainder division. For unsigned integers this is the same as numerator % denominator. Caller guarantees denominator > 0. + .documentation = + \\Remainder division. For unsigned integers this is the same as `numerator % denominator`. Caller guarantees `denominator > 0`. + \\ + \\ - `@rem(-5, 3) == -2` + \\ - `(@divTrunc(a, b) * b) + @rem(a, b) == a` + \\For a function that returns an error code, see `@import("std").math.rem`. , .arguments = &.{ "numerator: T", @@ -1195,10 +1219,12 @@ pub const builtins = [_]Builtin{ .name = "@returnAddress", .signature = "@returnAddress() usize", .snippet = "@returnAddress()", - .documentation = - \\ This function returns the address of the next machine code instruction that will be executed when the current function returns. - \\ The implications of this are target specific and not consistent across all platforms. - \\ This function is only valid within function scope. If the function gets inlined into a calling function, the returned address will apply to the calling function. + .documentation = + \\This function returns the address of the next machine code instruction that will be executed when the current function returns. + \\ + \\The implications of this are target specific and not consistent across all platforms. + \\ + \\This function is only valid within function scope. If the function gets inlined into a calling function, the returned address will apply to the calling function. , .arguments = &.{}, }, @@ -1206,8 +1232,8 @@ pub const builtins = [_]Builtin{ .name = "@setAlignStack", .signature = "@setAlignStack(comptime alignment: u29)", .snippet = "@setAlignStack(${1:comptime alignment: u29})", - .documentation = - \\ Ensures that a function will have a stack alignment of at least alignment bytes. + .documentation = + \\Ensures that a function will have a stack alignment of at least `alignment` bytes. , .arguments = &.{ "comptime alignment: u29", @@ -1217,8 +1243,8 @@ pub const builtins = [_]Builtin{ .name = "@setCold", .signature = "@setCold(is_cold: bool)", .snippet = "@setCold(${1:is_cold: bool})", - .documentation = - \\ Tells the optimizer that a function is rarely called. + .documentation = + \\Tells the optimizer that a function is rarely called. , .arguments = &.{ "is_cold: bool", @@ -1228,46 +1254,23 @@ pub const builtins = [_]Builtin{ .name = "@setEvalBranchQuota", .signature = "@setEvalBranchQuota(new_quota: usize)", .snippet = "@setEvalBranchQuota(${1:new_quota: usize})", - .documentation = - \\ Changes the maximum number of backwards branches that compile-time code execution can use before giving up and making a compile error. - \\ If the new_quota is smaller than the default quota (1000) or a previously explicitly set quota, it is ignored. - \\ Example: - \\test.zig - \\```zig - \\test "foo" { - \\ comptime { - \\ var i = 0; - \\ while (i < 1001) : (i += 1) {} + .documentation = + \\Changes the maximum number of backwards branches that compile-time code execution can use before giving up and making a compile error. + \\ + \\If the `new_quota` is smaller than the default quota (`1000`) or a previously explicitly set quota, it is ignored. + \\ + \\Example: + \\ + \\1001) : (i += 1) {} \\ } \\} \\``` - \\```zig - \\$ zig test test.zig - \\./docgen_tmp/test.zig:4:9: error: evaluation exceeded 1000 backwards branches - \\ while (i < 1001) : (i += 1) {} - \\ ^ - \\./docgen_tmp/test.zig:1:12: note: referenced here - \\test "foo" { - \\ ^ + \\Now we use `@setEvalBranchQuota`: \\ - \\``` - \\Now we use @setEvalBranchQuota: - \\test.zig - \\```zig - \\test "foo" { - \\ comptime { - \\ @setEvalBranchQuota(1001); - \\ var i = 0; - \\ while (i < 1001) : (i += 1) {} + \\1001) : (i += 1) {} \\ } \\} \\``` - \\```zig - \\$ zig test test.zig - \\1/1 test "foo"... OK - \\All 1 tests passed. - \\ - \\``` , .arguments = &.{ "new_quota: usize", @@ -1277,14 +1280,26 @@ pub const builtins = [_]Builtin{ .name = "@setFloatMode", .signature = "@setFloatMode(mode: @import(\"builtin\").FloatMode)", .snippet = "@setFloatMode(${1:mode: @import(\"builtin\").FloatMode})", - .documentation = - \\ Sets the floating point mode of the current scope. Possible values are: + .documentation = + \\Sets the floating point mode of the current scope. Possible values are: + \\ \\```zig \\pub const FloatMode = enum { \\ Strict, \\ Optimized, \\}; \\``` + \\ - `Strict` (default) - Floating point operations follow strict IEEE compliance. + \\ - `Optimized` - Floating point operations may do all of the following: + \\ - Assume the arguments and result are not NaN. Optimizations are required to retain defined behavior over NaNs, but the value of the result is undefined. + \\ - Assume the arguments and result are not +/-Inf. Optimizations are required to retain defined behavior over +/-Inf, but the value of the result is undefined. + \\ - Treat the sign of a zero argument or result as insignificant. + \\ - Use the reciprocal of an argument rather than perform division. + \\ - Perform floating-point contraction (e.g. fusing a multiply followed by an addition into a fused multiply-and-add). + \\ - Perform algebraically equivalent transformations that may change results in floating point (e.g. reassociate). + \\This is equivalent to + \\`-ffast-math`in GCC. + \\The floating point mode is inherited by child scopes, and can be overridden in any scope. You can set the floating point mode in a struct or module scope by using a comptime block. , .arguments = &.{ "mode: @import(\"builtin\").FloatMode", @@ -1294,9 +1309,9 @@ pub const builtins = [_]Builtin{ .name = "@setRuntimeSafety", .signature = "@setRuntimeSafety(safety_on: bool)", .snippet = "@setRuntimeSafety(${1:safety_on: bool})", - .documentation = - \\ Sets whether runtime safety checks are enabled for the scope that contains the function call. - \\test.zig + .documentation = + \\Sets whether runtime safety checks are enabled for the scope that contains the function call. + \\ \\```zig \\test "@setRuntimeSafety" { \\ // The builtin applies to the scope that it is called in. So here, integer overflow @@ -1309,7 +1324,6 @@ pub const builtins = [_]Builtin{ \\ @setRuntimeSafety(true); \\ var x: u8 = 255; \\ x += 1; - \\ \\ { \\ // The value can be overridden at any scope. So here integer overflow \\ // would not be caught in any build mode. @@ -1320,14 +1334,9 @@ pub const builtins = [_]Builtin{ \\ } \\} \\``` - \\```zig - \\$ zig test test.zig-OReleaseFast - \\1/1 test "@setRuntimeSafety"... integer overflow - \\error: the following test command crashed: - \\docgen_tmp/zig-cache/o/cb6de32279940f36da16caa4f64d8c67/test - \\ - \\``` - \\Note: it is planned to replace @setRuntimeSafety with @optimizeFor + \\Note: it is + \\[planned](https://github.com/ziglang/zig/issues/978)to replace `@setRuntimeSafety` with + \\`@optimizeFor` , .arguments = &.{ "safety_on: bool", @@ -1337,9 +1346,10 @@ pub const builtins = [_]Builtin{ .name = "@shlExact", .signature = "@shlExact(value: T, shift_amt: Log2T) T", .snippet = "@shlExact(${1:value: T}, ${2:shift_amt: Log2T})", - .documentation = - \\ Performs the left shift operation (<<). Caller guarantees that the shift will not shift any 1 bits out. - \\ The type of shift_amt is an unsigned integer with log2(T.bit_count) bits. This is because shift_amt >= T.bit_count is undefined behavior. + .documentation = + \\`). Caller guarantees that the shift will not shift any 1 bits out. + \\ + \\The type of `shift_amt` is an unsigned integer with `log2(T.bit_count)` bits. This is because `shift_amt >= T.bit_count` is undefined behavior. , .arguments = &.{ "value: T", @@ -1350,9 +1360,10 @@ pub const builtins = [_]Builtin{ .name = "@shlWithOverflow", .signature = "@shlWithOverflow(comptime T: type, a: T, shift_amt: Log2T, result: *T) bool", .snippet = "@shlWithOverflow(${1:comptime T: type}, ${2:a: T}, ${3:shift_amt: Log2T}, ${4:result: *T})", - .documentation = - \\ Performs result.* = a << b. If overflow or underflow occurs, stores the overflowed bits in result and returns true. If no overflow or underflow occurs, returns false. - \\ The type of shift_amt is an unsigned integer with log2(T.bit_count) bits. This is because shift_amt >= T.bit_count is undefined behavior. + .documentation = + \\b`. If overflow or underflow occurs, stores the overflowed bits in `result` and returns `true`. If no overflow or underflow occurs, returns `false`. + \\ + \\The type of `shift_amt` is an unsigned integer with `log2(T.bit_count)` bits. This is because `shift_amt >= T.bit_count` is undefined behavior. , .arguments = &.{ "comptime T: type", @@ -1365,9 +1376,10 @@ pub const builtins = [_]Builtin{ .name = "@shrExact", .signature = "@shrExact(value: T, shift_amt: Log2T) T", .snippet = "@shrExact(${1:value: T}, ${2:shift_amt: Log2T})", - .documentation = - \\ Performs the right shift operation (>>). Caller guarantees that the shift will not shift any 1 bits out. - \\ The type of shift_amt is an unsigned integer with log2(T.bit_count) bits. This is because shift_amt >= T.bit_count is undefined behavior. + .documentation = + \\Performs the right shift operation (`>>`). Caller guarantees that the shift will not shift any 1 bits out. + \\ + \\The type of `shift_amt` is an unsigned integer with `log2(T.bit_count)` bits. This is because `shift_amt >= T.bit_count` is undefined behavior. , .arguments = &.{ "value: T", @@ -1378,13 +1390,18 @@ pub const builtins = [_]Builtin{ .name = "@shuffle", .signature = "@shuffle(comptime E: type, a: std.meta.Vector(a_len, E), b: std.meta.Vector(b_len, E), comptime mask: std.meta.Vector(mask_len, i32)) std.meta.Vector(mask_len, E)", .snippet = "@shuffle(${1:comptime E: type}, ${2:a: std.meta.Vector(a_len, E)}, ${3:b: std.meta.Vector(b_len, E)}, ${4:comptime mask: std.meta.Vector(mask_len, i32)})", - .documentation = - \\ Constructs a new vector by selecting elements from a and b based on mask. - \\ Each element in mask selects an element from either a or b. Positive numbers select from a starting at 0. Negative values select from b, starting at -1 and going down. It is recommended to use the ~ operator from indexes from b so that both indexes can start from 0 (i.e. ~@as(i32, 0) is -1). - \\ For each element of mask, if it or the selected value from a or b is undefined, then the resulting element is undefined. - \\ a_len and b_len may differ in length. Out-of-bounds element indexes in mask result in compile errors. - \\ If a or b is undefined, it is equivalent to a vector of all undefined with the same length as the other vector. If both vectors are undefined, @shuffle returns a vector with all elements undefined. - \\ E must be an integer, float, pointer, or bool. The mask may be any vector length, and its length determines the result length. + .documentation = + \\Constructs a new [vector](https://ziglang.org/documentation/0.7.0/#Vectors) by selecting elements from `a` and `b` based on `mask`. + \\ + \\Each element in `mask` selects an element from either `a` or `b`. Positive numbers select from `a` starting at 0. Negative values select from `b`, starting at `-1` and going down. It is recommended to use the `~` operator from indexes from `b` so that both indexes can start from `0` (i.e. `~@as(i32, 0)` is `-1`). + \\ + \\For each element of `mask`, if it or the selected value from `a` or `b` is `undefined`, then the resulting element is `undefined`. + \\ + \\`a_len` and `b_len` may differ in length. Out-of-bounds element indexes in `mask` result in compile errors. + \\ + \\If `a` or `b` is `undefined`, it is equivalent to a vector of all `undefined` with the same length as the other vector. If both vectors are `undefined`, `@shuffle` returns a vector with all elements `undefined`. + \\ + \\`E` must be an [integer](https://ziglang.org/documentation/0.7.0/#Integers), [float](https://ziglang.org/documentation/0.7.0/#Floats), [pointer](https://ziglang.org/documentation/0.7.0/#Pointers), or `bool`. The mask may be any vector length, and its length determines the result length. , .arguments = &.{ "comptime E: type", @@ -1397,10 +1414,12 @@ pub const builtins = [_]Builtin{ .name = "@sizeOf", .signature = "@sizeOf(comptime T: type) comptime_int", .snippet = "@sizeOf(${1:comptime T: type})", - .documentation = - \\ This function returns the number of bytes it takes to store T in memory. The result is a target-specific compile time constant. - \\ This size may contain padding bytes. If there were two consecutive T in memory, this would be the offset in bytes between element at index 0 and the element at index 1. For integer, consider whether you want to use @sizeOf(T) or @typeInfo(T).Int.bits. - \\ This function measures the size at runtime. For types that are disallowed at runtime, such as comptime_int and type, the result is 0. + .documentation = + \\This function returns the number of bytes it takes to store `T` in memory. The result is a target-specific compile time constant. + \\ + \\This size may contain padding bytes. If there were two consecutive T in memory, this would be the offset in bytes between element at index 0 and the element at index 1. For [integer](https://ziglang.org/documentation/0.7.0/#Integers), consider whether you want to use `@sizeOf(T)` or `@typeInfo(T).Int.bits`. + \\ + \\This function measures the size at runtime. For types that are disallowed at runtime, such as `comptime_int` and `type`, the result is `0`. , .arguments = &.{ "comptime T: type", @@ -1410,13 +1429,12 @@ pub const builtins = [_]Builtin{ .name = "@splat", .signature = "@splat(comptime len: u32, scalar: anytype) std.meta.Vector(len, @TypeOf(scalar))", .snippet = "@splat(${1:comptime len: u32}, ${2:scalar: anytype})", - .documentation = - \\ Produces a vector of length len where each element is the value scalar: - \\test.zig + .documentation = + \\Produces a vector of length `len` where each element is the value `scalar`: + \\ \\```zig \\const std = @import("std"); \\const expect = std.testing.expect; - \\ \\test "vector @splat" { \\ const scalar: u32 = 5; \\ const result = @splat(4, scalar); @@ -1424,13 +1442,7 @@ pub const builtins = [_]Builtin{ \\ expect(std.mem.eql(u32, &@as([4]u32, result), &[_]u32{ 5, 5, 5, 5 })); \\} \\``` - \\```zig - \\$ zig test test.zig - \\1/1 test "vector @splat"... OK - \\All 1 tests passed. - \\ - \\``` - \\ scalar must be an integer, bool, float, or pointer. + \\`scalar` must be an [integer](https://ziglang.org/documentation/0.7.0/#Integers), [bool](https://ziglang.org/documentation/0.7.0/#Primitive-Types), [float](https://ziglang.org/documentation/0.7.0/#Floats), or [pointer](https://ziglang.org/documentation/0.7.0/#Pointers). , .arguments = &.{ "comptime len: u32", @@ -1441,9 +1453,29 @@ pub const builtins = [_]Builtin{ .name = "@reduce", .signature = "@reduce(comptime op: builtin.ReduceOp, value: anytype) std.meta.Child(value)", .snippet = "@reduce(${1:comptime op: builtin.ReduceOp}, ${2:value: anytype})", - .documentation = - \\ Transforms a vector into a scalar value by performing a sequential horizontal reduction of its elements using the specified specified operator op. - \\ Not every operator is available for every vector element type: + .documentation = + \\Transforms a [vector](https://ziglang.org/documentation/0.7.0/#Vectors) into a scalar value by performing a sequential horizontal reduction of its elements using the specified specified operator `op`. + \\ + \\Not every operator is available for every vector element type: + \\ + \\ - `.And`, `.Or`, `.Xor` are available for `bool` vectors, + \\ - `.Min`, `.Max`, `.Add`, `.Mul` are available for [floating point](https://ziglang.org/documentation/0.7.0/#Floats) vectors, + \\ - Every operator is available for [integer](https://ziglang.org/documentation/0.7.0/#Integers) vectors. + \\Note that `.Add` and `.Mul` reductions on integral types are wrapping; when applied on floating point types the operation associativity is preserved, unless the float mode is set to `Optimized`. + \\ + \\```zig + \\const std = @import("std"); + \\const expect = std.testing.expect; + \\test "vector @reduce" { + \\ const value: std.meta.Vector(4, i32) = [_]i32{ 1, -1, 1, -1 }; + \\ const result = value > @splat(4, @as(i32, 0)); + \\ // result is { true, false, true, false }; + \\ comptime expect(@TypeOf(result) == std.meta.Vector(4, bool)); + \\ const is_all_true = @reduce(.And, result); + \\ comptime expect(@TypeOf(is_all_true) == bool); + \\ expect(is_all_true == false); + \\} + \\``` , .arguments = &.{ "comptime op: builtin.ReduceOp", @@ -1454,32 +1486,23 @@ pub const builtins = [_]Builtin{ .name = "@src", .signature = "@src() std.builtin.SourceLocation", .snippet = "@src()", - .documentation = - \\ Returns a SourceLocation struct representing the function's name and location in the source code. This must be called in a function. - \\test.zig + .documentation = + \\Returns a `SourceLocation` struct representing the function's name and location in the source code. This must be called in a function. + \\ \\```zig \\const std = @import("std"); \\const expect = std.testing.expect; - \\ \\test "@src" { \\ doTheTest(); \\} - \\ \\fn doTheTest() void { \\ const src = @src(); - \\ \\ expect(src.line == 9); \\ expect(src.column == 17); \\ expect(std.mem.endsWith(u8, src.fn_name, "doTheTest")); \\ expect(std.mem.endsWith(u8, src.file, "test.zig")); \\} \\``` - \\```zig - \\$ zig test test.zig - \\1/1 test "@src"... OK - \\All 1 tests passed. - \\ - \\``` , .arguments = &.{}, }, @@ -1487,9 +1510,11 @@ pub const builtins = [_]Builtin{ .name = "@sqrt", .signature = "@sqrt(value: anytype) @TypeOf(value)", .snippet = "@sqrt(${1:value: anytype})", - .documentation = - \\ Performs the square root of a floating point number. Uses a dedicated hardware instruction when available. - \\ Supports Floats and Vectors of floats, with the caveat that some float operations are not yet implemented for all float types. + .documentation = + \\Performs the square root of a floating point number. Uses a dedicated hardware instruction when available. + \\ + \\Supports [Floats](https://ziglang.org/documentation/0.7.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.7.0/#Vectors) of floats, with the caveat that + \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). , .arguments = &.{ "value: anytype", @@ -1499,9 +1524,11 @@ pub const builtins = [_]Builtin{ .name = "@sin", .signature = "@sin(value: anytype) @TypeOf(value)", .snippet = "@sin(${1:value: anytype})", - .documentation = - \\ Sine trigometric function on a floating point number. Uses a dedicated hardware instruction when available. - \\ Supports Floats and Vectors of floats, with the caveat that some float operations are not yet implemented for all float types. + .documentation = + \\Sine trigometric function on a floating point number. Uses a dedicated hardware instruction when available. + \\ + \\Supports [Floats](https://ziglang.org/documentation/0.7.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.7.0/#Vectors) of floats, with the caveat that + \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). , .arguments = &.{ "value: anytype", @@ -1511,9 +1538,11 @@ pub const builtins = [_]Builtin{ .name = "@cos", .signature = "@cos(value: anytype) @TypeOf(value)", .snippet = "@cos(${1:value: anytype})", - .documentation = - \\ Cosine trigometric function on a floating point number. Uses a dedicated hardware instruction when available. - \\ Supports Floats and Vectors of floats, with the caveat that some float operations are not yet implemented for all float types. + .documentation = + \\Cosine trigometric function on a floating point number. Uses a dedicated hardware instruction when available. + \\ + \\Supports [Floats](https://ziglang.org/documentation/0.7.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.7.0/#Vectors) of floats, with the caveat that + \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). , .arguments = &.{ "value: anytype", @@ -1523,9 +1552,11 @@ pub const builtins = [_]Builtin{ .name = "@exp", .signature = "@exp(value: anytype) @TypeOf(value)", .snippet = "@exp(${1:value: anytype})", - .documentation = - \\ Base-e exponential function on a floating point number. Uses a dedicated hardware instruction when available. - \\ Supports Floats and Vectors of floats, with the caveat that some float operations are not yet implemented for all float types. + .documentation = + \\Base-e exponential function on a floating point number. Uses a dedicated hardware instruction when available. + \\ + \\Supports [Floats](https://ziglang.org/documentation/0.7.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.7.0/#Vectors) of floats, with the caveat that + \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). , .arguments = &.{ "value: anytype", @@ -1535,9 +1566,11 @@ pub const builtins = [_]Builtin{ .name = "@exp2", .signature = "@exp2(value: anytype) @TypeOf(value)", .snippet = "@exp2(${1:value: anytype})", - .documentation = - \\ Base-2 exponential function on a floating point number. Uses a dedicated hardware instruction when available. - \\ Supports Floats and Vectors of floats, with the caveat that some float operations are not yet implemented for all float types. + .documentation = + \\Base-2 exponential function on a floating point number. Uses a dedicated hardware instruction when available. + \\ + \\Supports [Floats](https://ziglang.org/documentation/0.7.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.7.0/#Vectors) of floats, with the caveat that + \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). , .arguments = &.{ "value: anytype", @@ -1547,9 +1580,11 @@ pub const builtins = [_]Builtin{ .name = "@log", .signature = "@log(value: anytype) @TypeOf(value)", .snippet = "@log(${1:value: anytype})", - .documentation = - \\ Returns the natural logarithm of a floating point number. Uses a dedicated hardware instruction when available. - \\ Supports Floats and Vectors of floats, with the caveat that some float operations are not yet implemented for all float types. + .documentation = + \\Returns the natural logarithm of a floating point number. Uses a dedicated hardware instruction when available. + \\ + \\Supports [Floats](https://ziglang.org/documentation/0.7.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.7.0/#Vectors) of floats, with the caveat that + \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). , .arguments = &.{ "value: anytype", @@ -1559,9 +1594,11 @@ pub const builtins = [_]Builtin{ .name = "@log2", .signature = "@log2(value: anytype) @TypeOf(value)", .snippet = "@log2(${1:value: anytype})", - .documentation = - \\ Returns the logarithm to the base 2 of a floating point number. Uses a dedicated hardware instruction when available. - \\ Supports Floats and Vectors of floats, with the caveat that some float operations are not yet implemented for all float types. + .documentation = + \\Returns the logarithm to the base 2 of a floating point number. Uses a dedicated hardware instruction when available. + \\ + \\Supports [Floats](https://ziglang.org/documentation/0.7.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.7.0/#Vectors) of floats, with the caveat that + \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). , .arguments = &.{ "value: anytype", @@ -1571,9 +1608,11 @@ pub const builtins = [_]Builtin{ .name = "@log10", .signature = "@log10(value: anytype) @TypeOf(value)", .snippet = "@log10(${1:value: anytype})", - .documentation = - \\ Returns the logarithm to the base 10 of a floating point number. Uses a dedicated hardware instruction when available. - \\ Supports Floats and Vectors of floats, with the caveat that some float operations are not yet implemented for all float types. + .documentation = + \\Returns the logarithm to the base 10 of a floating point number. Uses a dedicated hardware instruction when available. + \\ + \\Supports [Floats](https://ziglang.org/documentation/0.7.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.7.0/#Vectors) of floats, with the caveat that + \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). , .arguments = &.{ "value: anytype", @@ -1583,9 +1622,11 @@ pub const builtins = [_]Builtin{ .name = "@fabs", .signature = "@fabs(value: anytype) @TypeOf(value)", .snippet = "@fabs(${1:value: anytype})", - .documentation = - \\ Returns the absolute value of a floating point number. Uses a dedicated hardware instruction when available. - \\ Supports Floats and Vectors of floats, with the caveat that some float operations are not yet implemented for all float types. + .documentation = + \\Returns the absolute value of a floating point number. Uses a dedicated hardware instruction when available. + \\ + \\Supports [Floats](https://ziglang.org/documentation/0.7.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.7.0/#Vectors) of floats, with the caveat that + \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). , .arguments = &.{ "value: anytype", @@ -1595,9 +1636,11 @@ pub const builtins = [_]Builtin{ .name = "@floor", .signature = "@floor(value: anytype) @TypeOf(value)", .snippet = "@floor(${1:value: anytype})", - .documentation = - \\ Returns the largest integral value not greater than the given floating point number. Uses a dedicated hardware instruction when available. - \\ Supports Floats and Vectors of floats, with the caveat that some float operations are not yet implemented for all float types. + .documentation = + \\Returns the largest integral value not greater than the given floating point number. Uses a dedicated hardware instruction when available. + \\ + \\Supports [Floats](https://ziglang.org/documentation/0.7.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.7.0/#Vectors) of floats, with the caveat that + \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). , .arguments = &.{ "value: anytype", @@ -1607,9 +1650,11 @@ pub const builtins = [_]Builtin{ .name = "@ceil", .signature = "@ceil(value: anytype) @TypeOf(value)", .snippet = "@ceil(${1:value: anytype})", - .documentation = - \\ Returns the largest integral value not less than the given floating point number. Uses a dedicated hardware instruction when available. - \\ Supports Floats and Vectors of floats, with the caveat that some float operations are not yet implemented for all float types. + .documentation = + \\Returns the largest integral value not less than the given floating point number. Uses a dedicated hardware instruction when available. + \\ + \\Supports [Floats](https://ziglang.org/documentation/0.7.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.7.0/#Vectors) of floats, with the caveat that + \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). , .arguments = &.{ "value: anytype", @@ -1619,9 +1664,11 @@ pub const builtins = [_]Builtin{ .name = "@trunc", .signature = "@trunc(value: anytype) @TypeOf(value)", .snippet = "@trunc(${1:value: anytype})", - .documentation = - \\ Rounds the given floating point number to an integer, towards zero. Uses a dedicated hardware instruction when available. - \\ Supports Floats and Vectors of floats, with the caveat that some float operations are not yet implemented for all float types. + .documentation = + \\Rounds the given floating point number to an integer, towards zero. Uses a dedicated hardware instruction when available. + \\ + \\Supports [Floats](https://ziglang.org/documentation/0.7.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.7.0/#Vectors) of floats, with the caveat that + \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). , .arguments = &.{ "value: anytype", @@ -1631,9 +1678,11 @@ pub const builtins = [_]Builtin{ .name = "@round", .signature = "@round(value: anytype) @TypeOf(value)", .snippet = "@round(${1:value: anytype})", - .documentation = - \\ Rounds the given floating point number to an integer, away from zero. Uses a dedicated hardware instruction when available. - \\ Supports Floats and Vectors of floats, with the caveat that some float operations are not yet implemented for all float types. + .documentation = + \\Rounds the given floating point number to an integer, away from zero. Uses a dedicated hardware instruction when available. + \\ + \\Supports [Floats](https://ziglang.org/documentation/0.7.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.7.0/#Vectors) of floats, with the caveat that + \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). , .arguments = &.{ "value: anytype", @@ -1643,8 +1692,8 @@ pub const builtins = [_]Builtin{ .name = "@subWithOverflow", .signature = "@subWithOverflow(comptime T: type, a: T, b: T, result: *T) bool", .snippet = "@subWithOverflow(${1:comptime T: type}, ${2:a: T}, ${3:b: T}, ${4:result: *T})", - .documentation = - \\ Performs result.* = a - b. If overflow or underflow occurs, stores the overflowed bits in result and returns true. If no overflow or underflow occurs, returns false. + .documentation = + \\Performs `result.* = a - b`. If overflow or underflow occurs, stores the overflowed bits in `result` and returns `true`. If no overflow or underflow occurs, returns `false`. , .arguments = &.{ "comptime T: type", @@ -1657,9 +1706,10 @@ pub const builtins = [_]Builtin{ .name = "@tagName", .signature = "@tagName(value: anytype) []const u8", .snippet = "@tagName(${1:value: anytype})", - .documentation = - \\ Converts an enum value or union value to a slice of bytes representing the name. - \\If the enum is non-exhaustive and the tag value does not map to a name, it invokes safety-checked Undefined Behavior. + .documentation = + \\Converts an enum value or union value to a slice of bytes representing the name. + \\ + \\If the enum is non-exhaustive and the tag value does not map to a name, it invokes safety-checked [Undefined Behavior](https://ziglang.org/documentation/0.7.0/#Undefined-Behavior). , .arguments = &.{ "value: anytype", @@ -1669,9 +1719,10 @@ pub const builtins = [_]Builtin{ .name = "@TagType", .signature = "@TagType(T: type) type", .snippet = "@TagType(${1:T: type})", - .documentation = - \\ For an enum, returns the integer type that is used to store the enumeration value. - \\ For a union, returns the enum type that is used to store the tag value. + .documentation = + \\For an enum, returns the integer type that is used to store the enumeration value. + \\ + \\For a union, returns the enum type that is used to store the tag value. , .arguments = &.{ "T: type", @@ -1681,38 +1732,28 @@ pub const builtins = [_]Builtin{ .name = "@This", .signature = "@This() type", .snippet = "@This()", - .documentation = - \\ Returns the innermost struct, enum, or union that this function call is inside. This can be useful for an anonymous struct that needs to refer to itself: - \\test.zig + .documentation = + \\Returns the innermost struct, enum, or union that this function call is inside. This can be useful for an anonymous struct that needs to refer to itself: + \\ \\```zig \\const std = @import("std"); \\const expect = std.testing.expect; - \\ \\test "@This()" { \\ var items = [_]i32{ 1, 2, 3, 4 }; \\ const list = List(i32){ .items = items[0..] }; \\ expect(list.length() == 4); \\} - \\ \\fn List(comptime T: type) type { \\ return struct { \\ const Self = @This(); - \\ \\ items: []T, - \\ \\ fn length(self: Self) usize { \\ return self.items.len; \\ } \\ }; \\} \\``` - \\```zig - \\$ zig test test.zig - \\1/1 test "@This()"... OK - \\All 1 tests passed. - \\ - \\``` - \\ When @This() is used at global scope, it returns a reference to the struct that corresponds to the current file. + \\When `@This()` is used at global scope, it returns a reference to the struct that corresponds to the current file. , .arguments = &.{}, }, @@ -1720,54 +1761,29 @@ pub const builtins = [_]Builtin{ .name = "@truncate", .signature = "@truncate(comptime T: type, integer: anytype) T", .snippet = "@truncate(${1:comptime T: type}, ${2:integer: anytype})", - .documentation = - \\ This function truncates bits from an integer type, resulting in a smaller or same-sized integer type. - \\ The following produces safety-checked Undefined Behavior: - \\test.zig + .documentation = + \\This function truncates bits from an integer type, resulting in a smaller or same-sized integer type. + \\ + \\The following produces safety-checked [Undefined Behavior](https://ziglang.org/documentation/0.7.0/#Undefined-Behavior): + \\ \\```zig \\test "integer cast panic" { \\ var a: u16 = 0xabcd; \\ var b: u8 = @intCast(u8, a); \\} \\``` - \\```zig - \\$ zig test test.zig - \\1/1 test "integer cast panic"... integer cast truncated bits - \\/home/andy/Downloads/zig/docgen_tmp/test.zig:3:17: 0x205995 in test "integer cast panic" (test) - \\ var b: u8 = @intCast(u8, a); - \\ ^ - \\/home/andy/Downloads/zig/lib/std/special/test_runner.zig:61:28: 0x22d991 in std.special.main (test) - \\ } else test_fn.func(); - \\ ^ - \\/home/andy/Downloads/zig/lib/std/start.zig:334:37: 0x20729d in std.start.posixCallMainAndExit (test) - \\ const result = root.main() catch |err| { - \\ ^ - \\/home/andy/Downloads/zig/lib/std/start.zig:162:5: 0x206fd2 in std.start._start (test) - \\ @call(.{ .modifier = .never_inline }, posixCallMainAndExit, .{}); - \\ ^ - \\error: the following test command crashed: - \\docgen_tmp/zig-cache/o/2e7f715609483f0cd9100db66b70c1a0/test + \\However this is well defined and working code: \\ - \\``` - \\ However this is well defined and working code: - \\truncate.zig \\```zig \\const std = @import("std"); \\const expect = std.testing.expect; - \\ \\test "integer truncation" { \\ var a: u16 = 0xabcd; \\ var b: u8 = @truncate(u8, a); \\ expect(b == 0xcd); \\} \\``` - \\```zig - \\$ zig test truncate.zig - \\1/1 test "integer truncation"... OK - \\All 1 tests passed. - \\ - \\``` - \\ This function always truncates the significant bits of the integer, regardless of endianness on the target platform. + \\This function always truncates the significant bits of the integer, regardless of endianness on the target platform. , .arguments = &.{ "comptime T: type", @@ -1778,9 +1794,38 @@ pub const builtins = [_]Builtin{ .name = "@Type", .signature = "@Type(comptime info: @import(\"builtin\").TypeInfo) type", .snippet = "@Type(${1:comptime info: @import(\"builtin\").TypeInfo})", - .documentation = - \\ This function is the inverse of @typeInfo. It reifies type information into a type. - \\ It is available for the following types: + .documentation = + \\This function is the inverse of [@typeInfo](https://ziglang.org/documentation/0.7.0/#typeInfo). It reifies type information into a `type`. + \\ + \\It is available for the following types: + \\ + \\ - `type` + \\ - `noreturn` + \\ - `void` + \\ - `bool` + \\ - [Integers](https://ziglang.org/documentation/0.7.0/#Integers) - The maximum bit count for an integer type is `65535`. + \\ - [Floats](https://ziglang.org/documentation/0.7.0/#Floats) + \\ - [Pointers](https://ziglang.org/documentation/0.7.0/#Pointers) + \\ - `comptime_int` + \\ - `comptime_float` + \\ - `@TypeOf(undefined)` + \\ - `@TypeOf(null)` + \\ - [Arrays](https://ziglang.org/documentation/0.7.0/#Arrays) + \\ - [Optionals](https://ziglang.org/documentation/0.7.0/#Optionals) + \\ - [Error Set Type](https://ziglang.org/documentation/0.7.0/#Error-Set-Type) + \\ - [Error Union Type](https://ziglang.org/documentation/0.7.0/#Error-Union-Type) + \\ - [Vectors](https://ziglang.org/documentation/0.7.0/#Vectors) + \\ - [opaque](https://ziglang.org/documentation/0.7.0/#opaque) + \\ - [@Frame](https://ziglang.org/documentation/0.7.0/#Frame) + \\ - `anyframe` + \\ - [struct](https://ziglang.org/documentation/0.7.0/#struct) + \\ - [enum](https://ziglang.org/documentation/0.7.0/#enum) + \\ - [Enum Literals](https://ziglang.org/documentation/0.7.0/#Enum-Literals) + \\ - [union](https://ziglang.org/documentation/0.7.0/#union) + \\For these types, `@Type` is not available: + \\ + \\ - [Functions](https://ziglang.org/documentation/0.7.0/#Functions) + \\ - BoundFn , .arguments = &.{ "comptime info: @import(\"builtin\").TypeInfo", @@ -1790,9 +1835,10 @@ pub const builtins = [_]Builtin{ .name = "@typeInfo", .signature = "@typeInfo(comptime T: type) @import(\"std\").builtin.TypeInfo", .snippet = "@typeInfo(${1:comptime T: type})", - .documentation = - \\ Provides type reflection. - \\ For structs, unions, enums, and error sets, the fields are guaranteed to be in the same order as declared. For declarations, the order is unspecified. + .documentation = + \\Provides type reflection. + \\ + \\For [structs](https://ziglang.org/documentation/0.7.0/#struct), [unions](https://ziglang.org/documentation/0.7.0/#union), [enums](https://ziglang.org/documentation/0.7.0/#enum), and [error sets](https://ziglang.org/documentation/0.7.0/#Error-Set-Type), the fields are guaranteed to be in the same order as declared. For declarations, the order is unspecified. , .arguments = &.{ "comptime T: type", @@ -1802,8 +1848,8 @@ pub const builtins = [_]Builtin{ .name = "@typeName", .signature = "@typeName(T: type) [N]u8", .snippet = "@typeName(${1:T: type})", - .documentation = - \\ This function returns the string representation of a type, as an array. It is equivalent to a string literal of the type name. + .documentation = + \\This function returns the string representation of a type, as an array. It is equivalent to a string literal of the type name. , .arguments = &.{ "T: type", @@ -1813,32 +1859,26 @@ pub const builtins = [_]Builtin{ .name = "@TypeOf", .signature = "@TypeOf(...) type", .snippet = "@TypeOf(${1:...})", - .documentation = - \\ @TypeOf is a special builtin function that takes any (nonzero) number of expressions as parameters and returns the type of the result, using Peer Type Resolution. - \\ The expressions are evaluated, however they are guaranteed to have no runtime side-effects: - \\test.zig + .documentation = + \\`@TypeOf` is a special builtin function that takes any (nonzero) number of expressions as parameters and returns the type of the result, using [Peer Type Resolution](https://ziglang.org/documentation/0.7.0/#Peer-Type-Resolution). + \\ + \\The expressions are evaluated, however they are guaranteed to have no + \\**runtime** side-effects: + \\ \\```zig \\const std = @import("std"); \\const expect = std.testing.expect; - \\ \\test "no runtime side effects" { \\ var data: i32 = 0; \\ const T = @TypeOf(foo(i32, &data)); \\ comptime expect(T == i32); \\ expect(data == 0); \\} - \\ \\fn foo(comptime T: type, ptr: *T) T { \\ ptr.* += 1; \\ return ptr.*; \\} \\``` - \\```zig - \\$ zig test test.zig - \\1/1 test "no runtime side effects"... OK - \\All 1 tests passed. - \\ - \\``` , .arguments = &.{ "...", @@ -1848,9 +1888,10 @@ pub const builtins = [_]Builtin{ .name = "@unionInit", .signature = "@unionInit(comptime Union: type, comptime active_field_name: []const u8, init_expr) Union", .snippet = "@unionInit(${1:comptime Union: type}, ${2:comptime active_field_name: []const u8}, ${3:init_expr})", - .documentation = - \\ This is the same thing as union initialization syntax, except that the field name is a comptime-known value rather than an identifier token. - \\ @unionInit forwards its result location to init_expr. + .documentation = + \\This is the same thing as [union](https://ziglang.org/documentation/0.7.0/#union) initialization syntax, except that the field name is a [comptime](https://ziglang.org/documentation/0.7.0/#comptime)-known value rather than an identifier token. + \\ + \\`@unionInit` forwards its [result location](https://ziglang.org/documentation/0.7.0/#Result-Location-Semantics) to `init_expr`. , .arguments = &.{ "comptime Union: type", @@ -1859,3 +1900,5 @@ pub const builtins = [_]Builtin{ }, }, }; + +// DO NOT EDIT diff --git a/src/data/0.7.1.zig b/src/data/0.7.1.zig index 6b8ff95..7bb0e82 100644 --- a/src/data/0.7.1.zig +++ b/src/data/0.7.1.zig @@ -1,3 +1,8 @@ +//! DO NOT EDIT +//! If you want to update this file run: +//! `zig build gen -- --generate-version-data 0.7.1` (requires an internet connection) +//! GENERATED BY src/config_gen/config_gen.zig + const Builtin = struct { name: []const u8, signature: []const u8, @@ -11,8 +16,8 @@ pub const builtins = [_]Builtin{ .name = "@addWithOverflow", .signature = "@addWithOverflow(comptime T: type, a: T, b: T, result: *T) bool", .snippet = "@addWithOverflow(${1:comptime T: type}, ${2:a: T}, ${3:b: T}, ${4:result: *T})", - .documentation = - \\ Performs result.* = a + b. If overflow or underflow occurs, stores the overflowed bits in result and returns true. If no overflow or underflow occurs, returns false. + .documentation = + \\Performs `result.* = a + b`. If overflow or underflow occurs, stores the overflowed bits in `result` and returns `true`. If no overflow or underflow occurs, returns `false`. , .arguments = &.{ "comptime T: type", @@ -25,9 +30,10 @@ pub const builtins = [_]Builtin{ .name = "@alignCast", .signature = "@alignCast(comptime alignment: u29, ptr: anytype) anytype", .snippet = "@alignCast(${1:comptime alignment: u29}, ${2:ptr: anytype})", - .documentation = - \\ ptr can be *T, fn(), ?*T, ?fn(), or []T. It returns the same type as ptr except with the alignment adjusted to the new value. - \\A pointer alignment safety check is added to the generated code to make sure the pointer is aligned as promised. + .documentation = + \\`ptr` can be `*T`, `fn()`, `?*T`, `?fn()`, or `[]T`. It returns the same type as `ptr` except with the alignment adjusted to the new value. + \\ + \\A [pointer alignment safety check](https://ziglang.org/documentation/0.7.1/#Incorrect-Pointer-Alignment) is added to the generated code to make sure the pointer is aligned as promised. , .arguments = &.{ "comptime alignment: u29", @@ -38,15 +44,16 @@ pub const builtins = [_]Builtin{ .name = "@alignOf", .signature = "@alignOf(comptime T: type) comptime_int", .snippet = "@alignOf(${1:comptime T: type})", - .documentation = - \\ This function returns the number of bytes that this type should be aligned to for the current target to match the C ABI. When the child type of a pointer has this alignment, the alignment can be omitted from the type. + .documentation = + \\This function returns the number of bytes that this type should be aligned to for the current target to match the C ABI. When the child type of a pointer has this alignment, the alignment can be omitted from the type. + \\ \\```zig \\const expect = @import("std").testing.expect; \\comptime { \\ expect(*u32 == *align(@alignOf(u32)) u32); \\} \\``` - \\ The result is a target-specific compile time constant. It is guaranteed to be less than or equal to @sizeOf(T). + \\The result is a target-specific compile time constant. It is guaranteed to be less than or equal to [@sizeOf(T)](https://ziglang.org/documentation/0.7.1/#sizeOf). , .arguments = &.{ "comptime T: type", @@ -56,8 +63,8 @@ pub const builtins = [_]Builtin{ .name = "@as", .signature = "@as(comptime T: type, expression) T", .snippet = "@as(${1:comptime T: type}, ${2:expression})", - .documentation = - \\ Performs Type Coercion. This cast is allowed when the conversion is unambiguous and safe, and is the preferred way to convert between types, whenever possible. + .documentation = + \\Performs [Type Coercion](https://ziglang.org/documentation/0.7.1/#Type-Coercion). This cast is allowed when the conversion is unambiguous and safe, and is the preferred way to convert between types, whenever possible. , .arguments = &.{ "comptime T: type", @@ -67,16 +74,17 @@ pub const builtins = [_]Builtin{ .{ .name = "@asyncCall", .signature = "@asyncCall(frame_buffer: []align(@alignOf(@Frame(anyAsyncFunction))) u8, result_ptr, function_ptr, args: anytype) anyframe->T", - .snippet = "@asyncCall(${1:frame_buffer: []align(@alignOf(@Frame(anyAsyncFunction))) u8}, ${2:result_ptr}, ${3:function_ptr}, ${4:args: anytype})", - .documentation = - \\ @asyncCall performs an async call on a function pointer, which may or may not be an async function. - \\ The provided frame_buffer must be large enough to fit the entire function frame. This size can be determined with @frameSize. To provide a too-small buffer invokes safety-checked Undefined Behavior. - \\ result_ptr is optional (null may be provided). If provided, the function call will write its result directly to the result pointer, which will be available to read after await completes. Any result location provided to await will copy the result from result_ptr. - \\test.zig + .snippet = "@asyncCall(${1:frame_buffer: []align(@alignOf(@Frame(anyAsyncFunction)})", + .documentation = + \\`@asyncCall` performs an `async` call on a function pointer, which may or may not be an [async function](https://ziglang.org/documentation/0.7.1/#Async-Functions). + \\ + \\The provided `frame_buffer` must be large enough to fit the entire function frame. This size can be determined with [@frameSize](https://ziglang.org/documentation/0.7.1/#frameSize). To provide a too-small buffer invokes safety-checked [Undefined Behavior](https://ziglang.org/documentation/0.7.1/#Undefined-Behavior). + \\ + \\`result_ptr` is optional ([null](https://ziglang.org/documentation/0.7.1/#null) may be provided). If provided, the function call will write its result directly to the result pointer, which will be available to read after [await](https://ziglang.org/documentation/0.7.1/#Async-and-Await) completes. Any result location provided to `await` will copy the result from `result_ptr`. + \\ \\```zig \\const std = @import("std"); \\const expect = std.testing.expect; - \\ \\test "async fn pointer in a struct field" { \\ var data: i32 = 1; \\ const Foo = struct { @@ -89,34 +97,25 @@ pub const builtins = [_]Builtin{ \\ resume f; \\ expect(data == 4); \\} - \\ \\fn func(y: *i32) void { \\ defer y.* += 2; \\ y.* += 1; \\ suspend; \\} \\``` - \\```zig - \\$ zig test test.zig - \\1/1 test "async fn pointer in a struct field"... OK - \\All 1 tests passed. - \\ - \\``` , .arguments = &.{ - "frame_buffer: []align(@alignOf(@Frame(anyAsyncFunction))) u8", - "result_ptr", - "function_ptr", - "args: anytype", + "frame_buffer: []align(@alignOf(@Frame(anyAsyncFunction)", }, }, .{ .name = "@atomicLoad", .signature = "@atomicLoad(comptime T: type, ptr: *const T, comptime ordering: builtin.AtomicOrder) T", .snippet = "@atomicLoad(${1:comptime T: type}, ${2:ptr: *const T}, ${3:comptime ordering: builtin.AtomicOrder})", - .documentation = - \\ This builtin function atomically dereferences a pointer and returns the value. - \\ T must be a pointer, a bool, a float, an integer or an enum. + .documentation = + \\This builtin function atomically dereferences a pointer and returns the value. + \\ + \\`T` must be a pointer, a `bool`, a float, an integer or an enum. , .arguments = &.{ "comptime T: type", @@ -128,10 +127,22 @@ pub const builtins = [_]Builtin{ .name = "@atomicRmw", .signature = "@atomicRmw(comptime T: type, ptr: *T, comptime op: builtin.AtomicRmwOp, operand: T, comptime ordering: builtin.AtomicOrder) T", .snippet = "@atomicRmw(${1:comptime T: type}, ${2:ptr: *T}, ${3:comptime op: builtin.AtomicRmwOp}, ${4:operand: T}, ${5:comptime ordering: builtin.AtomicOrder})", - .documentation = - \\ This builtin function atomically modifies memory and then returns the previous value. - \\ T must be a pointer, a bool, a float, an integer or an enum. - \\ Supported operations: + .documentation = + \\This builtin function atomically modifies memory and then returns the previous value. + \\ + \\`T` must be a pointer, a `bool`, a float, an integer or an enum. + \\ + \\Supported operations: + \\ + \\ - `.Xchg` - stores the operand unmodified. Supports enums, integers and floats. + \\ - `.Add` - for integers, twos complement wraparound addition. Also supports [Floats](https://ziglang.org/documentation/0.7.1/#Floats). + \\ - `.Sub` - for integers, twos complement wraparound subtraction. Also supports [Floats](https://ziglang.org/documentation/0.7.1/#Floats). + \\ - `.And` - bitwise and + \\ - `.Nand` - bitwise nand + \\ - `.Or` - bitwise or + \\ - `.Xor` - bitwise xor + \\ - `.Max` - stores the operand if it is larger. Supports integers and floats. + \\ - `.Min` - stores the operand if it is smaller. Supports integers and floats. , .arguments = &.{ "comptime T: type", @@ -145,9 +156,10 @@ pub const builtins = [_]Builtin{ .name = "@atomicStore", .signature = "@atomicStore(comptime T: type, ptr: *T, value: T, comptime ordering: builtin.AtomicOrder) void", .snippet = "@atomicStore(${1:comptime T: type}, ${2:ptr: *T}, ${3:value: T}, ${4:comptime ordering: builtin.AtomicOrder})", - .documentation = - \\ This builtin function atomically stores a value. - \\ T must be a pointer, a bool, a float, an integer or an enum. + .documentation = + \\This builtin function atomically stores a value. + \\ + \\`T` must be a pointer, a `bool`, a float, an integer or an enum. , .arguments = &.{ "comptime T: type", @@ -160,11 +172,18 @@ pub const builtins = [_]Builtin{ .name = "@bitCast", .signature = "@bitCast(comptime DestType: type, value: anytype) DestType", .snippet = "@bitCast(${1:comptime DestType: type}, ${2:value: anytype})", - .documentation = - \\ Converts a value of one type to another type. - \\ Asserts that @sizeOf(@TypeOf(value)) == @sizeOf(DestType). - \\ Asserts that @typeInfo(DestType) != .Pointer. Use @ptrCast or @intToPtr if you need this. - \\ Can be used for these things for example: + .documentation = + \\Converts a value of one type to another type. + \\ + \\Asserts that `@sizeOf(@TypeOf(value)) == @sizeOf(DestType)`. + \\ + \\Asserts that `@typeInfo(DestType) != .Pointer`. Use `@ptrCast` or `@intToPtr` if you need this. + \\ + \\Can be used for these things for example: + \\ + \\ - Convert `f32` to `u32` bits + \\ - Convert `i32` to `u32` preserving twos complement + \\Works at compile-time if `value` is known at compile time. It's a compile error to bitcast a struct to a scalar type of the same size since structs have undefined layout. However if the struct is packed then it works. , .arguments = &.{ "comptime DestType: type", @@ -175,9 +194,10 @@ pub const builtins = [_]Builtin{ .name = "@bitOffsetOf", .signature = "@bitOffsetOf(comptime T: type, comptime field_name: []const u8) comptime_int", .snippet = "@bitOffsetOf(${1:comptime T: type}, ${2:comptime field_name: []const u8})", - .documentation = - \\ Returns the bit offset of a field relative to its containing struct. - \\ For non packed structs, this will always be divisible by 8. For packed structs, non-byte-aligned fields will share a byte offset, but they will have different bit offsets. + .documentation = + \\Returns the bit offset of a field relative to its containing struct. + \\ + \\For non [packed structs](https://ziglang.org/documentation/0.7.1/#packed-struct), this will always be divisible by `8`. For packed structs, non-byte-aligned fields will share a byte offset, but they will have different bit offsets. , .arguments = &.{ "comptime T: type", @@ -188,9 +208,10 @@ pub const builtins = [_]Builtin{ .name = "@boolToInt", .signature = "@boolToInt(value: bool) u1", .snippet = "@boolToInt(${1:value: bool})", - .documentation = - \\ Converts true to u1(1) and false to u1(0). - \\ If the value is known at compile-time, the return type is comptime_int instead of u1. + .documentation = + \\Converts `true` to `u1(1)` and `false` to `u1(0)`. + \\ + \\If the value is known at compile-time, the return type is `comptime_int` instead of `u1`. , .arguments = &.{ "value: bool", @@ -200,9 +221,10 @@ pub const builtins = [_]Builtin{ .name = "@bitSizeOf", .signature = "@bitSizeOf(comptime T: type) comptime_int", .snippet = "@bitSizeOf(${1:comptime T: type})", - .documentation = - \\ This function returns the number of bits it takes to store T in memory. The result is a target-specific compile time constant. - \\ This function measures the size at runtime. For types that are disallowed at runtime, such as comptime_int and type, the result is 0. + .documentation = + \\This function returns the number of bits it takes to store `T` in memory. The result is a target-specific compile time constant. + \\ + \\This function measures the size at runtime. For types that are disallowed at runtime, such as `comptime_int` and `type`, the result is `0`. , .arguments = &.{ "comptime T: type", @@ -212,9 +234,10 @@ pub const builtins = [_]Builtin{ .name = "@breakpoint", .signature = "@breakpoint()", .snippet = "@breakpoint()", - .documentation = - \\ This function inserts a platform-specific debug trap instruction which causes debuggers to break there. - \\ This function is only valid within function scope. + .documentation = + \\This function inserts a platform-specific debug trap instruction which causes debuggers to break there. + \\ + \\This function is only valid within function scope. , .arguments = &.{}, }, @@ -222,9 +245,10 @@ pub const builtins = [_]Builtin{ .name = "@mulAdd", .signature = "@mulAdd(comptime T: type, a: T, b: T, c: T) T", .snippet = "@mulAdd(${1:comptime T: type}, ${2:a: T}, ${3:b: T}, ${4:c: T})", - .documentation = - \\ Fused multiply add, similar to (a * b) + c, except only rounds once, and is thus more accurate. - \\ Supports Floats and Vectors of floats. + .documentation = + \\Fused multiply add, similar to `(a * b) + c`, except only rounds once, and is thus more accurate. + \\ + \\Supports Floats and Vectors of floats. , .arguments = &.{ "comptime T: type", @@ -237,11 +261,14 @@ pub const builtins = [_]Builtin{ .name = "@byteSwap", .signature = "@byteSwap(comptime T: type, operand: T) T", .snippet = "@byteSwap(${1:comptime T: type}, ${2:operand: T})", - .documentation = - \\T must be an integer type with bit count evenly divisible by 8. - \\operand may be an integer or vector. - \\ Swaps the byte order of the integer. This converts a big endian integer to a little endian integer, and converts a little endian integer to a big endian integer. - \\ Note that for the purposes of memory layout with respect to endianness, the integer type should be related to the number of bytes reported by @sizeOf bytes. This is demonstrated with u24. @sizeOf(u24) == 4, which means that a u24 stored in memory takes 4 bytes, and those 4 bytes are what are swapped on a little vs big endian system. On the other hand, if T is specified to be u24, then only 3 bytes are reversed. + .documentation = + \\`T` must be an integer type with bit count evenly divisible by 8. + \\ + \\`operand` may be an [integer](https://ziglang.org/documentation/0.7.1/#Integers) or [vector](https://ziglang.org/documentation/0.7.1/#Vectors). + \\ + \\Swaps the byte order of the integer. This converts a big endian integer to a little endian integer, and converts a little endian integer to a big endian integer. + \\ + \\Note that for the purposes of memory layout with respect to endianness, the integer type should be related to the number of bytes reported by [@sizeOf](https://ziglang.org/documentation/0.7.1/#sizeOf) bytes. This is demonstrated with `u24`. `@sizeOf(u24) == 4`, which means that a `u24` stored in memory takes 4 bytes, and those 4 bytes are what are swapped on a little vs big endian system. On the other hand, if `T` is specified to be `u24`, then only 3 bytes are reversed. , .arguments = &.{ "comptime T: type", @@ -252,10 +279,12 @@ pub const builtins = [_]Builtin{ .name = "@bitReverse", .signature = "@bitReverse(comptime T: type, integer: T) T", .snippet = "@bitReverse(${1:comptime T: type}, ${2:integer: T})", - .documentation = - \\T accepts any integer type. - \\ Reverses the bitpattern of an integer value, including the sign bit if applicable. - \\ For example 0b10110110 (u8 = 182, i8 = -74) becomes 0b01101101 (u8 = 109, i8 = 109). + .documentation = + \\`T` accepts any integer type. + \\ + \\Reverses the bitpattern of an integer value, including the sign bit if applicable. + \\ + \\For example 0b10110110 (`u8 = 182`, `i8 = -74`) becomes 0b01101101 (`u8 = 109`, `i8 = 109`). , .arguments = &.{ "comptime T: type", @@ -266,8 +295,8 @@ pub const builtins = [_]Builtin{ .name = "@byteOffsetOf", .signature = "@byteOffsetOf(comptime T: type, comptime field_name: []const u8) comptime_int", .snippet = "@byteOffsetOf(${1:comptime T: type}, ${2:comptime field_name: []const u8})", - .documentation = - \\ Returns the byte offset of a field relative to its containing struct. + .documentation = + \\Returns the byte offset of a field relative to its containing struct. , .arguments = &.{ "comptime T: type", @@ -278,61 +307,46 @@ pub const builtins = [_]Builtin{ .name = "@call", .signature = "@call(options: std.builtin.CallOptions, function: anytype, args: anytype) anytype", .snippet = "@call(${1:options: std.builtin.CallOptions}, ${2:function: anytype}, ${3:args: anytype})", - .documentation = - \\ Calls a function, in the same way that invoking an expression with parentheses does: - \\call.zig + .documentation = + \\Calls a function, in the same way that invoking an expression with parentheses does: + \\ \\```zig \\const expect = @import("std").testing.expect; - \\ \\test "noinline function call" { \\ expect(@call(.{}, add, .{3, 9}) == 12); \\} - \\ \\fn add(a: i32, b: i32) i32 { \\ return a + b; \\} \\``` - \\```zig - \\$ zig test call.zig - \\1/1 test "noinline function call"... OK - \\All 1 tests passed. + \\`@call` allows more flexibility than normal function call syntax does. The `CallOptions` struct is reproduced here: \\ - \\``` - \\ @call allows more flexibility than normal function call syntax does. The CallOptions struct is reproduced here: \\```zig \\pub const CallOptions = struct { \\ modifier: Modifier = .auto, \\ stack: ?[]align(std.Target.stack_align) u8 = null, - \\ \\ pub const Modifier = enum { \\ /// Equivalent to function call syntax. \\ auto, - \\ \\ /// Equivalent to async keyword used with function call syntax. \\ async_kw, - \\ \\ /// Prevents tail call optimization. This guarantees that the return \\ /// address will point to the callsite, as opposed to the callsite's \\ /// callsite. If the call is otherwise required to be tail-called \\ /// or inlined, a compile error is emitted instead. \\ never_tail, - \\ \\ /// Guarantees that the call will not be inlined. If the call is \\ /// otherwise required to be inlined, a compile error is emitted instead. \\ never_inline, - \\ \\ /// Asserts that the function call will not suspend. This allows a \\ /// non-async function to call an async function. \\ no_async, - \\ \\ /// Guarantees that the call will be generated with tail call optimization. \\ /// If this is not possible, a compile error is emitted instead. \\ always_tail, - \\ \\ /// Guarantees that the call will inlined at the callsite. \\ /// If this is not possible, a compile error is emitted instead. \\ always_inline, - \\ \\ /// Evaluates the call at compile-time. If the call cannot be completed at \\ /// compile-time, a compile error is emitted instead. \\ compile_time, @@ -350,17 +364,17 @@ pub const builtins = [_]Builtin{ .name = "@cDefine", .signature = "@cDefine(comptime name: []u8, value)", .snippet = "@cDefine(${1:comptime name: []u8}, ${2:value})", - .documentation = - \\ This function can only occur inside @cImport. - \\ This appends #define $name $value to the @cImport temporary buffer. - \\ To define without a value, like this: - \\```zig - \\#define _GNU_SOURCE - \\``` - \\ Use the void value, like this: - \\```zig - \\@cDefine("_GNU_SOURCE", {}) - \\``` + .documentation = + \\This function can only occur inside `@cImport`. + \\ + \\This appends + \\`#define $name $value`to the `@cImport` temporary buffer. + \\ + \\To define without a value, like this: + \\ + \\`#define _GNU_SOURCE`Use the void value, like this: + \\ + \\`@cDefine("_GNU_SOURCE", {})` , .arguments = &.{ "comptime name: []u8", @@ -371,11 +385,17 @@ pub const builtins = [_]Builtin{ .name = "@cImport", .signature = "@cImport(expression) type", .snippet = "@cImport(${1:expression})", - .documentation = - \\ This function parses C code and imports the functions, types, variables, and compatible macro definitions into a new empty struct type, and then returns that type. - \\ expression is interpreted at compile time. The builtin functions @cInclude, @cDefine, and @cUndef work within this expression, appending to a temporary buffer which is then parsed as C code. - \\ Usually you should only have one @cImport in your entire application, because it saves the compiler from invoking clang multiple times, and prevents inline functions from being duplicated. - \\ Reasons for having multiple @cImport expressions would be: + .documentation = + \\This function parses C code and imports the functions, types, variables, and compatible macro definitions into a new empty struct type, and then returns that type. + \\ + \\`expression` is interpreted at compile time. The builtin functions `@cInclude`, `@cDefine`, and `@cUndef` work within this expression, appending to a temporary buffer which is then parsed as C code. + \\ + \\Usually you should only have one `@cImport` in your entire application, because it saves the compiler from invoking clang multiple times, and prevents inline functions from being duplicated. + \\ + \\Reasons for having multiple `@cImport` expressions would be: + \\ + \\ - To avoid a symbol collision, for example if foo.h and bar.h both + \\`#define CONNECTION_COUNT` - To analyze the C code with different preprocessor defines , .arguments = &.{ "expression", @@ -385,9 +405,11 @@ pub const builtins = [_]Builtin{ .name = "@cInclude", .signature = "@cInclude(comptime path: []u8)", .snippet = "@cInclude(${1:comptime path: []u8})", - .documentation = - \\ This function can only occur inside @cImport. - \\ This appends #include <$path>\n to the c_import temporary buffer. + .documentation = + \\This function can only occur inside `@cImport`. + \\ + \\This appends + \\`#include <$path>\n`to the `c_import` temporary buffer. , .arguments = &.{ "comptime path: []u8", @@ -397,10 +419,12 @@ pub const builtins = [_]Builtin{ .name = "@clz", .signature = "@clz(comptime T: type, integer: T)", .snippet = "@clz(${1:comptime T: type}, ${2:integer: T})", - .documentation = - \\ This function counts the number of most-significant (leading in a big-Endian sense) zeroes in integer. - \\ If integer is known at comptime, the return type is comptime_int. Otherwise, the return type is an unsigned integer with the minimum number of bits that can represent the bit count of the integer type. - \\ If integer is zero, @clz returns the bit width of integer type T. + .documentation = + \\This function counts the number of most-significant (leading in a big-Endian sense) zeroes in `integer`. + \\ + \\If `integer` is known at [comptime](https://ziglang.org/documentation/0.7.1/#comptime), the return type is `comptime_int`. Otherwise, the return type is an unsigned integer with the minimum number of bits that can represent the bit count of the integer type. + \\ + \\If `integer` is zero, `@clz` returns the bit width of integer type `T`. , .arguments = &.{ "comptime T: type", @@ -411,8 +435,9 @@ pub const builtins = [_]Builtin{ .name = "@cmpxchgStrong", .signature = "@cmpxchgStrong(comptime T: type, ptr: *T, expected_value: T, new_value: T, success_order: AtomicOrder, fail_order: AtomicOrder) ?T", .snippet = "@cmpxchgStrong(${1:comptime T: type}, ${2:ptr: *T}, ${3:expected_value: T}, ${4:new_value: T}, ${5:success_order: AtomicOrder}, ${6:fail_order: AtomicOrder})", - .documentation = - \\ This function performs a strong atomic compare exchange operation. It's the equivalent of this code, except atomic: + .documentation = + \\This function performs a strong atomic compare exchange operation. It's the equivalent of this code, except atomic: + \\ \\```zig \\fn cmpxchgStrongButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_value: T) ?T { \\ const old_value = ptr.*; @@ -424,9 +449,11 @@ pub const builtins = [_]Builtin{ \\ } \\} \\``` - \\ If you are using cmpxchg in a loop, @cmpxchgWeak is the better choice, because it can be implemented more efficiently in machine instructions. - \\ T must be a pointer, a bool, a float, an integer or an enum. - \\@typeInfo(@TypeOf(ptr)).Pointer.alignment must be >= @sizeOf(T). + \\If you are using cmpxchg in a loop, [@cmpxchgWeak](https://ziglang.org/documentation/0.7.1/#cmpxchgWeak) is the better choice, because it can be implemented more efficiently in machine instructions. + \\ + \\`T` must be a pointer, a `bool`, a float, an integer or an enum. + \\ + \\`@typeInfo(@TypeOf(ptr)).Pointer.alignment` must be `>= @sizeOf(T).` , .arguments = &.{ "comptime T: type", @@ -441,8 +468,9 @@ pub const builtins = [_]Builtin{ .name = "@cmpxchgWeak", .signature = "@cmpxchgWeak(comptime T: type, ptr: *T, expected_value: T, new_value: T, success_order: AtomicOrder, fail_order: AtomicOrder) ?T", .snippet = "@cmpxchgWeak(${1:comptime T: type}, ${2:ptr: *T}, ${3:expected_value: T}, ${4:new_value: T}, ${5:success_order: AtomicOrder}, ${6:fail_order: AtomicOrder})", - .documentation = - \\ This function performs a weak atomic compare exchange operation. It's the equivalent of this code, except atomic: + .documentation = + \\This function performs a weak atomic compare exchange operation. It's the equivalent of this code, except atomic: + \\ \\```zig \\fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_value: T) ?T { \\ const old_value = ptr.*; @@ -454,9 +482,11 @@ pub const builtins = [_]Builtin{ \\ } \\} \\``` - \\ If you are using cmpxchg in a loop, the sporadic failure will be no problem, and cmpxchgWeak is the better choice, because it can be implemented more efficiently in machine instructions. However if you need a stronger guarantee, use @cmpxchgStrong. - \\ T must be a pointer, a bool, a float, an integer or an enum. - \\@typeInfo(@TypeOf(ptr)).Pointer.alignment must be >= @sizeOf(T). + \\If you are using cmpxchg in a loop, the sporadic failure will be no problem, and `cmpxchgWeak` is the better choice, because it can be implemented more efficiently in machine instructions. However if you need a stronger guarantee, use [@cmpxchgStrong](https://ziglang.org/documentation/0.7.1/#cmpxchgStrong). + \\ + \\`T` must be a pointer, a `bool`, a float, an integer or an enum. + \\ + \\`@typeInfo(@TypeOf(ptr)).Pointer.alignment` must be `>= @sizeOf(T).` , .arguments = &.{ "comptime T: type", @@ -471,9 +501,10 @@ pub const builtins = [_]Builtin{ .name = "@compileError", .signature = "@compileError(comptime msg: []u8)", .snippet = "@compileError(${1:comptime msg: []u8})", - .documentation = - \\ This function, when semantically analyzed, causes a compile error with the message msg. - \\ There are several ways that code avoids being semantically checked, such as using if or switch with compile time constants, and comptime functions. + .documentation = + \\This function, when semantically analyzed, causes a compile error with the message `msg`. + \\ + \\There are several ways that code avoids being semantically checked, such as using `if` or `switch` with compile time constants, and `comptime` functions. , .arguments = &.{ "comptime msg: []u8", @@ -483,71 +514,41 @@ pub const builtins = [_]Builtin{ .name = "@compileLog", .signature = "@compileLog(args: ...)", .snippet = "@compileLog(${1:args: ...})", - .documentation = - \\ This function prints the arguments passed to it at compile-time. - \\ To prevent accidentally leaving compile log statements in a codebase, a compilation error is added to the build, pointing to the compile log statement. This error prevents code from being generated, but does not otherwise interfere with analysis. - \\ This function can be used to do "printf debugging" on compile-time executing code. - \\test.zig + .documentation = + \\This function prints the arguments passed to it at compile-time. + \\ + \\To prevent accidentally leaving compile log statements in a codebase, a compilation error is added to the build, pointing to the compile log statement. This error prevents code from being generated, but does not otherwise interfere with analysis. + \\ + \\This function can be used to do "printf debugging" on compile-time executing code. + \\ \\```zig \\const print = @import("std").debug.print; - \\ \\const num1 = blk: { \\ var val1: i32 = 99; \\ @compileLog("comptime val1 = ", val1); \\ val1 = val1 + 1; \\ break :blk val1; \\}; - \\ \\test "main" { \\ @compileLog("comptime in main"); - \\ \\ print("Runtime in main, num1 = {}.\n", .{num1}); \\} \\``` - \\```zig - \\$ zig test test.zig - \\| *"comptime in main" - \\| *"comptime val1 = ", 99 - \\./docgen_tmp/test.zig:11:5: error: found compile log statement - \\ @compileLog("comptime in main"); - \\ ^ - \\./docgen_tmp/test.zig:1:35: note: referenced here - \\const print = @import("std").debug.print; - \\ ^ - \\./docgen_tmp/test.zig:13:5: note: referenced here - \\ print("Runtime in main, num1 = {}.\n", .{num1}); - \\ ^ - \\./docgen_tmp/test.zig:5:5: error: found compile log statement - \\ @compileLog("comptime val1 = ", val1); - \\ ^ - \\./docgen_tmp/test.zig:13:46: note: referenced here - \\ print("Runtime in main, num1 = {}.\n", .{num1}); - \\ ^ + \\will ouput: + \\ + \\If all `@compileLog` calls are removed or not encountered by analysis, the program compiles successfully and the generated executable prints: \\ - \\``` - \\ will ouput: - \\ If all @compileLog calls are removed or not encountered by analysis, the program compiles successfully and the generated executable prints: - \\test.zig \\```zig \\const print = @import("std").debug.print; - \\ \\const num1 = blk: { \\ var val1: i32 = 99; \\ val1 = val1 + 1; \\ break :blk val1; \\}; - \\ \\test "main" { \\ print("Runtime in main, num1 = {}.\n", .{num1}); \\} \\``` - \\```zig - \\$ zig test test.zig - \\1/1 test "main"... Runtime in main, num1 = 100. - \\OK - \\All 1 tests passed. - \\ - \\``` , .arguments = &.{ "args: ...", @@ -557,10 +558,12 @@ pub const builtins = [_]Builtin{ .name = "@ctz", .signature = "@ctz(comptime T: type, integer: T)", .snippet = "@ctz(${1:comptime T: type}, ${2:integer: T})", - .documentation = - \\ This function counts the number of least-significant (trailing in a big-Endian sense) zeroes in integer. - \\ If integer is known at comptime, the return type is comptime_int. Otherwise, the return type is an unsigned integer with the minimum number of bits that can represent the bit count of the integer type. - \\ If integer is zero, @ctz returns the bit width of integer type T. + .documentation = + \\This function counts the number of least-significant (trailing in a big-Endian sense) zeroes in `integer`. + \\ + \\If `integer` is known at [comptime](https://ziglang.org/documentation/0.7.1/#comptime), the return type is `comptime_int`. Otherwise, the return type is an unsigned integer with the minimum number of bits that can represent the bit count of the integer type. + \\ + \\If `integer` is zero, `@ctz` returns the bit width of integer type `T`. , .arguments = &.{ "comptime T: type", @@ -571,9 +574,11 @@ pub const builtins = [_]Builtin{ .name = "@cUndef", .signature = "@cUndef(comptime name: []u8)", .snippet = "@cUndef(${1:comptime name: []u8})", - .documentation = - \\ This function can only occur inside @cImport. - \\ This appends #undef $name to the @cImport temporary buffer. + .documentation = + \\This function can only occur inside `@cImport`. + \\ + \\This appends + \\`#undef $name`to the `@cImport` temporary buffer. , .arguments = &.{ "comptime name: []u8", @@ -583,8 +588,12 @@ pub const builtins = [_]Builtin{ .name = "@divExact", .signature = "@divExact(numerator: T, denominator: T) T", .snippet = "@divExact(${1:numerator: T}, ${2:denominator: T})", - .documentation = - \\ Exact division. Caller guarantees denominator != 0 and @divTrunc(numerator, denominator) * denominator == numerator. + .documentation = + \\Exact division. Caller guarantees `denominator != 0` and `@divTrunc(numerator, denominator) * denominator == numerator`. + \\ + \\ - `@divExact(6, 3) == 2` + \\ - `@divExact(a, b) * b == a` + \\For a function that returns a possible error code, use `@import("std").math.divExact`. , .arguments = &.{ "numerator: T", @@ -595,8 +604,12 @@ pub const builtins = [_]Builtin{ .name = "@divFloor", .signature = "@divFloor(numerator: T, denominator: T) T", .snippet = "@divFloor(${1:numerator: T}, ${2:denominator: T})", - .documentation = - \\ Floored division. Rounds toward negative infinity. For unsigned integers it is the same as numerator / denominator. Caller guarantees denominator != 0 and !(@typeInfo(T) == .Int and T.is_signed and numerator == std.math.minInt(T) and denominator == -1). + .documentation = + \\Floored division. Rounds toward negative infinity. For unsigned integers it is the same as `numerator / denominator`. Caller guarantees `denominator != 0` and `!(@typeInfo(T) == .Int and T.is_signed and numerator == std.math.minInt(T) and denominator == -1)`. + \\ + \\ - `@divFloor(-5, 3) == -2` + \\ - `(@divFloor(a, b) * b) + @mod(a, b) == a` + \\For a function that returns a possible error code, use `@import("std").math.divFloor`. , .arguments = &.{ "numerator: T", @@ -607,8 +620,12 @@ pub const builtins = [_]Builtin{ .name = "@divTrunc", .signature = "@divTrunc(numerator: T, denominator: T) T", .snippet = "@divTrunc(${1:numerator: T}, ${2:denominator: T})", - .documentation = - \\ Truncated division. Rounds toward zero. For unsigned integers it is the same as numerator / denominator. Caller guarantees denominator != 0 and !(@typeInfo(T) == .Int and T.is_signed and numerator == std.math.minInt(T) and denominator == -1). + .documentation = + \\Truncated division. Rounds toward zero. For unsigned integers it is the same as `numerator / denominator`. Caller guarantees `denominator != 0` and `!(@typeInfo(T) == .Int and T.is_signed and numerator == std.math.minInt(T) and denominator == -1)`. + \\ + \\ - `@divTrunc(-5, 3) == -1` + \\ - `(@divTrunc(a, b) * b) + @rem(a, b) == a` + \\For a function that returns a possible error code, use `@import("std").math.divTrunc`. , .arguments = &.{ "numerator: T", @@ -619,9 +636,10 @@ pub const builtins = [_]Builtin{ .name = "@embedFile", .signature = "@embedFile(comptime path: []const u8) *const [X:0]u8", .snippet = "@embedFile(${1:comptime path: []const u8})", - .documentation = - \\ This function returns a compile time constant pointer to null-terminated, fixed-size array with length equal to the byte count of the file given by path. The contents of the array are the contents of the file. This is equivalent to a string literal with the file contents. - \\ path is absolute or relative to the current file, just like @import. + .documentation = + \\This function returns a compile time constant pointer to null-terminated, fixed-size array with length equal to the byte count of the file given by `path`. The contents of the array are the contents of the file. This is equivalent to a [string literal](https://ziglang.org/documentation/0.7.1/#String-Literals-and-Character-Literals) with the file contents. + \\ + \\`path` is absolute or relative to the current file, just like `@import`. , .arguments = &.{ "comptime path: []const u8", @@ -631,9 +649,10 @@ pub const builtins = [_]Builtin{ .name = "@enumToInt", .signature = "@enumToInt(enum_or_tagged_union: anytype) anytype", .snippet = "@enumToInt(${1:enum_or_tagged_union: anytype})", - .documentation = - \\ Converts an enumeration value into its integer tag type. When a tagged union is passed, the tag value is used as the enumeration value. - \\ If there is only one possible enum value, the resut is a comptime_int known at comptime. + .documentation = + \\Converts an enumeration value into its integer tag type. When a tagged union is passed, the tag value is used as the enumeration value. + \\ + \\If there is only one possible enum value, the resut is a `comptime_int` known at [comptime](https://ziglang.org/documentation/0.7.1/#comptime). , .arguments = &.{ "enum_or_tagged_union: anytype", @@ -643,9 +662,10 @@ pub const builtins = [_]Builtin{ .name = "@errorName", .signature = "@errorName(err: anyerror) []const u8", .snippet = "@errorName(${1:err: anyerror})", - .documentation = - \\ This function returns the string representation of an error. The string representation of error.OutOfMem is "OutOfMem". - \\ If there are no calls to @errorName in an entire application, or all calls have a compile-time known value for err, then no error name table will be generated. + .documentation = + \\This function returns the string representation of an error. The string representation of `error.OutOfMem` is `"OutOfMem"`. + \\ + \\If there are no calls to `@errorName` in an entire application, or all calls have a compile-time known value for `err`, then no error name table will be generated. , .arguments = &.{ "err: anyerror", @@ -655,8 +675,8 @@ pub const builtins = [_]Builtin{ .name = "@errorReturnTrace", .signature = "@errorReturnTrace() ?*builtin.StackTrace", .snippet = "@errorReturnTrace()", - .documentation = - \\ If the binary is built with error return tracing, and this function is invoked in a function that calls a function with an error or error union return type, returns a stack trace object. Otherwise returns null. + .documentation = + \\If the binary is built with error return tracing, and this function is invoked in a function that calls a function with an error or error union return type, returns a stack trace object. Otherwise returns [null](https://ziglang.org/documentation/0.7.1/#null). , .arguments = &.{}, }, @@ -664,8 +684,15 @@ pub const builtins = [_]Builtin{ .name = "@errorToInt", .signature = "@errorToInt(err: anytype) std.meta.IntType(false, @sizeOf(anyerror) * 8)", .snippet = "@errorToInt(${1:err: anytype})", - .documentation = - \\ Supports the following types: + .documentation = + \\Supports the following types: + \\ + \\ - [The Global Error Set](https://ziglang.org/documentation/0.7.1/#The-Global-Error-Set) + \\ - [Error Set Type](https://ziglang.org/documentation/0.7.1/#Error-Set-Type) + \\ - [Error Union Type](https://ziglang.org/documentation/0.7.1/#Error-Union-Type) + \\Converts an error to the integer representation of an error. + \\ + \\It is generally recommended to avoid this cast, as the integer representation of an error is not stable across source code changes. , .arguments = &.{ "err: anytype", @@ -675,8 +702,8 @@ pub const builtins = [_]Builtin{ .name = "@errSetCast", .signature = "@errSetCast(comptime T: DestType, value: anytype) DestType", .snippet = "@errSetCast(${1:comptime T: DestType}, ${2:value: anytype})", - .documentation = - \\ Converts an error value from one error set to another error set. Attempting to convert an error which is not in the destination error set results in safety-protected Undefined Behavior. + .documentation = + \\Converts an error value from one error set to another error set. Attempting to convert an error which is not in the destination error set results in safety-protected [Undefined Behavior](https://ziglang.org/documentation/0.7.1/#Undefined-Behavior). , .arguments = &.{ "comptime T: DestType", @@ -687,40 +714,26 @@ pub const builtins = [_]Builtin{ .name = "@export", .signature = "@export(target: anytype, comptime options: std.builtin.ExportOptions) void", .snippet = "@export(${1:target: anytype}, ${2:comptime options: std.builtin.ExportOptions})", - .documentation = - \\ Creates a symbol in the output object file. - \\ This function can be called from a comptime block to conditionally export symbols. When target is a function with the C calling convention and options.linkage is Strong, this is equivalent to the export keyword used on a function: - \\test.zig + .documentation = + \\Creates a symbol in the output object file. + \\ + \\This function can be called from a [comptime](https://ziglang.org/documentation/0.7.1/#comptime) block to conditionally export symbols. When `target` is a function with the C calling convention and `options.linkage` is `Strong`, this is equivalent to the `export` keyword used on a function: + \\ \\```zig \\comptime { \\ @export(internalName, .{ .name = "foo", .linkage = .Strong }); \\} - \\ \\fn internalName() callconv(.C) void {} \\``` - \\```zig - \\$ zig build-obj test.zig - \\``` \\This is equivalent to: - \\test.zig - \\```zig - \\export fn foo() void {} - \\``` - \\```zig - \\$ zig build-obj test.zig - \\``` - \\Note that even when using export, @"foo" syntax can be used to choose any string for the symbol name: - \\test.zig - \\```zig - \\export fn @"A function name that is a complete sentence."() void {} - \\``` - \\```zig - \\$ zig build-obj test.zig - \\``` - \\ When looking at the resulting object, you can see the symbol is used verbatim: - \\```zig - \\00000000000001f0 T A function name that is a complete sentence. - \\``` + \\ + \\`export fn foo() void {}` + \\Note that even when using `export`, `@"foo"` syntax can be used to choose any string for the symbol name: + \\ + \\`export fn @"A function name that is a complete sentence."() void {}` + \\When looking at the resulting object, you can see the symbol is used verbatim: + \\ + \\`00000000000001f0 T A function name that is a complete sentence.` , .arguments = &.{ "target: anytype", @@ -731,9 +744,10 @@ pub const builtins = [_]Builtin{ .name = "@fence", .signature = "@fence(order: AtomicOrder)", .snippet = "@fence(${1:order: AtomicOrder})", - .documentation = - \\ The fence function is used to introduce happens-before edges between operations. - \\ AtomicOrder can be found with @import("builtin").AtomicOrder. + .documentation = + \\The `fence` function is used to introduce happens-before edges between operations. + \\ + \\`AtomicOrder` can be found with `@import("builtin").AtomicOrder`. , .arguments = &.{ "order: AtomicOrder", @@ -743,34 +757,24 @@ pub const builtins = [_]Builtin{ .name = "@field", .signature = "@field(lhs: anytype, comptime field_name: []const u8) (field)", .snippet = "@field(${1:lhs: anytype}, ${2:comptime field_name: []const u8})", - .documentation = - \\Performs field access by a compile-time string. - \\test.zig + .documentation = + \\Performs field access by a compile-time string. + \\ \\```zig \\const std = @import("std"); - \\ \\const Point = struct { \\ x: u32, \\ y: u32 \\}; - \\ \\test "field access by string" { \\ const expect = std.testing.expect; \\ var p = Point {.x = 0, .y = 0}; - \\ \\ @field(p, "x") = 4; \\ @field(p, "y") = @field(p, "x") + 1; - \\ \\ expect(@field(p, "x") == 4); \\ expect(@field(p, "y") == 5); \\} \\``` - \\```zig - \\$ zig test test.zig - \\1/1 test "field access by string"... OK - \\All 1 tests passed. - \\ - \\``` , .arguments = &.{ "lhs: anytype", @@ -781,8 +785,8 @@ pub const builtins = [_]Builtin{ .name = "@fieldParentPtr", .signature = "@fieldParentPtr(comptime ParentType: type, comptime field_name: []const u8, field_ptr: *T) *ParentType", .snippet = "@fieldParentPtr(${1:comptime ParentType: type}, ${2:comptime field_name: []const u8}, ${3:field_ptr: *T})", - .documentation = - \\ Given a pointer to a field, returns the base pointer of a struct. + .documentation = + \\Given a pointer to a field, returns the base pointer of a struct. , .arguments = &.{ "comptime ParentType: type", @@ -794,8 +798,8 @@ pub const builtins = [_]Builtin{ .name = "@floatCast", .signature = "@floatCast(comptime DestType: type, value: anytype) DestType", .snippet = "@floatCast(${1:comptime DestType: type}, ${2:value: anytype})", - .documentation = - \\ Convert from one float type to another. This cast is safe, but may cause the numeric value to lose precision. + .documentation = + \\Convert from one float type to another. This cast is safe, but may cause the numeric value to lose precision. , .arguments = &.{ "comptime DestType: type", @@ -806,9 +810,10 @@ pub const builtins = [_]Builtin{ .name = "@floatToInt", .signature = "@floatToInt(comptime DestType: type, float: anytype) DestType", .snippet = "@floatToInt(${1:comptime DestType: type}, ${2:float: anytype})", - .documentation = - \\ Converts the integer part of a floating point number to the destination type. - \\ If the integer part of the floating point number cannot fit in the destination type, it invokes safety-checked Undefined Behavior. + .documentation = + \\Converts the integer part of a floating point number to the destination type. + \\ + \\If the integer part of the floating point number cannot fit in the destination type, it invokes safety-checked [Undefined Behavior](https://ziglang.org/documentation/0.7.1/#Undefined-Behavior). , .arguments = &.{ "comptime DestType: type", @@ -819,9 +824,10 @@ pub const builtins = [_]Builtin{ .name = "@frame", .signature = "@frame() *@Frame(func)", .snippet = "@frame()", - .documentation = - \\ This function returns a pointer to the frame for a given function. This type can be coerced to anyframe->T and to anyframe, where T is the return type of the function in scope. - \\ This function does not mark a suspension point, but it does cause the function in scope to become an async function. + .documentation = + \\This function returns a pointer to the frame for a given function. This type can be [coerced](https://ziglang.org/documentation/0.7.1/#Type-Coercion) to `anyframe->T` and to `anyframe`, where `T` is the return type of the function in scope. + \\ + \\This function does not mark a suspension point, but it does cause the function in scope to become an [async function](https://ziglang.org/documentation/0.7.1/#Async-Functions). , .arguments = &.{}, }, @@ -829,28 +835,21 @@ pub const builtins = [_]Builtin{ .name = "@Frame", .signature = "@Frame(func: anytype) type", .snippet = "@Frame(${1:func: anytype})", - .documentation = - \\ This function returns the frame type of a function. This works for Async Functions as well as any function without a specific calling convention. - \\ This type is suitable to be used as the return type of async which allows one to, for example, heap-allocate an async function frame: - \\test.zig + .documentation = + \\This function returns the frame type of a function. This works for [Async Functions](https://ziglang.org/documentation/0.7.1/#Async-Functions) as well as any function without a specific calling convention. + \\ + \\This type is suitable to be used as the return type of [async](https://ziglang.org/documentation/0.7.1/#Async-and-Await) which allows one to, for example, heap-allocate an async function frame: + \\ \\```zig \\const std = @import("std"); - \\ \\test "heap allocated frame" { \\ const frame = try std.heap.page_allocator.create(@Frame(func)); \\ frame.* = async func(); \\} - \\ \\fn func() void { \\ suspend; \\} \\``` - \\```zig - \\$ zig test test.zig - \\1/1 test "heap allocated frame"... OK - \\All 1 tests passed. - \\ - \\``` , .arguments = &.{ "func: anytype", @@ -860,10 +859,12 @@ pub const builtins = [_]Builtin{ .name = "@frameAddress", .signature = "@frameAddress() usize", .snippet = "@frameAddress()", - .documentation = - \\ This function returns the base pointer of the current stack frame. - \\ The implications of this are target specific and not consistent across all platforms. The frame address may not be available in release mode due to aggressive optimizations. - \\ This function is only valid within function scope. + .documentation = + \\This function returns the base pointer of the current stack frame. + \\ + \\The implications of this are target specific and not consistent across all platforms. The frame address may not be available in release mode due to aggressive optimizations. + \\ + \\This function is only valid within function scope. , .arguments = &.{}, }, @@ -871,9 +872,10 @@ pub const builtins = [_]Builtin{ .name = "@frameSize", .signature = "@frameSize() usize", .snippet = "@frameSize()", - .documentation = - \\ This is the same as @sizeOf(@Frame(func)), where func may be runtime-known. - \\ This function is typically used in conjunction with @asyncCall. + .documentation = + \\This is the same as `@sizeOf(@Frame(func))`, where `func` may be runtime-known. + \\ + \\This function is typically used in conjunction with [@asyncCall](https://ziglang.org/documentation/0.7.1/#asyncCall). , .arguments = &.{}, }, @@ -881,39 +883,28 @@ pub const builtins = [_]Builtin{ .name = "@hasDecl", .signature = "@hasDecl(comptime Container: type, comptime name: []const u8) bool", .snippet = "@hasDecl(${1:comptime Container: type}, ${2:comptime name: []const u8})", - .documentation = - \\ Returns whether or not a struct, enum, or union has a declaration matching name. - \\test.zig + .documentation = + \\Returns whether or not a [struct](https://ziglang.org/documentation/0.7.1/#struct), [enum](https://ziglang.org/documentation/0.7.1/#enum), or [union](https://ziglang.org/documentation/0.7.1/#union) has a declaration matching `name`. + \\ \\```zig \\const std = @import("std"); \\const expect = std.testing.expect; - \\ \\const Foo = struct { \\ nope: i32, - \\ \\ pub var blah = "xxx"; \\ const hi = 1; \\}; - \\ \\test "@hasDecl" { \\ expect(@hasDecl(Foo, "blah")); - \\ \\ // Even though `hi` is private, @hasDecl returns true because this test is \\ // in the same file scope as Foo. It would return false if Foo was declared \\ // in a different file. \\ expect(@hasDecl(Foo, "hi")); - \\ \\ // @hasDecl is for declarations; not fields. \\ expect(!@hasDecl(Foo, "nope")); \\ expect(!@hasDecl(Foo, "nope1234")); \\} \\``` - \\```zig - \\$ zig test test.zig - \\1/1 test "@hasDecl"... OK - \\All 1 tests passed. - \\ - \\``` , .arguments = &.{ "comptime Container: type", @@ -924,10 +915,12 @@ pub const builtins = [_]Builtin{ .name = "@hasField", .signature = "@hasField(comptime Container: type, comptime name: []const u8) bool", .snippet = "@hasField(${1:comptime Container: type}, ${2:comptime name: []const u8})", - .documentation = + .documentation = \\Returns whether the field name of a struct, union, or enum exists. - \\ The result is a compile time constant. - \\ It does not include functions, variables, or constants. + \\ + \\The result is a compile time constant. + \\ + \\It does not include functions, variables, or constants. , .arguments = &.{ "comptime Container: type", @@ -938,12 +931,20 @@ pub const builtins = [_]Builtin{ .name = "@import", .signature = "@import(comptime path: []u8) type", .snippet = "@import(${1:comptime path: []u8})", - .documentation = - \\ This function finds a zig file corresponding to path and adds it to the build, if it is not already added. - \\ Zig source files are implicitly structs, with a name equal to the file's basename with the extension truncated. @import returns the struct type corresponding to the file. - \\ Declarations which have the pub keyword may be referenced from a different source file than the one they are declared in. - \\ path can be a relative path or it can be the name of a package. If it is a relative path, it is relative to the file that contains the @import function call. - \\ The following packages are always available: + .documentation = + \\This function finds a zig file corresponding to `path` and adds it to the build, if it is not already added. + \\ + \\Zig source files are implicitly structs, with a name equal to the file's basename with the extension truncated. `@import` returns the struct type corresponding to the file. + \\ + \\Declarations which have the `pub` keyword may be referenced from a different source file than the one they are declared in. + \\ + \\`path` can be a relative path or it can be the name of a package. If it is a relative path, it is relative to the file that contains the `@import` function call. + \\ + \\The following packages are always available: + \\ + \\ - `@import("std")` - Zig Standard Library + \\ - `@import("builtin")` - Compiler-provided types and variables. The command + \\`zig builtin`outputs the source to stdout for reference. , .arguments = &.{ "comptime path: []u8", @@ -953,9 +954,10 @@ pub const builtins = [_]Builtin{ .name = "@intCast", .signature = "@intCast(comptime DestType: type, int: anytype) DestType", .snippet = "@intCast(${1:comptime DestType: type}, ${2:int: anytype})", - .documentation = - \\ Converts an integer to another integer while keeping the same numerical value. Attempting to convert a number which is out of range of the destination type results in safety-protected Undefined Behavior. - \\ If T is comptime_int, then this is semantically equivalent to Type Coercion. + .documentation = + \\Converts an integer to another integer while keeping the same numerical value. Attempting to convert a number which is out of range of the destination type results in safety-protected [Undefined Behavior](https://ziglang.org/documentation/0.7.1/#Undefined-Behavior). + \\ + \\If `T` is `comptime_int`, then this is semantically equivalent to [Type Coercion](https://ziglang.org/documentation/0.7.1/#Type-Coercion). , .arguments = &.{ "comptime DestType: type", @@ -966,9 +968,10 @@ pub const builtins = [_]Builtin{ .name = "@intToEnum", .signature = "@intToEnum(comptime DestType: type, int_value: @TagType(DestType)) DestType", .snippet = "@intToEnum(${1:comptime DestType: type}, ${2:int_value: @TagType(DestType)})", - .documentation = - \\ Converts an integer into an enum value. - \\ Attempting to convert an integer which represents no value in the chosen enum type invokes safety-checked Undefined Behavior. + .documentation = + \\Converts an integer into an [enum](https://ziglang.org/documentation/0.7.1/#enum) value. + \\ + \\Attempting to convert an integer which represents no value in the chosen enum type invokes safety-checked [Undefined Behavior](https://ziglang.org/documentation/0.7.1/#Undefined-Behavior). , .arguments = &.{ "comptime DestType: type", @@ -978,22 +981,24 @@ pub const builtins = [_]Builtin{ .{ .name = "@intToError", .signature = "@intToError(value: std.meta.IntType(false, @sizeOf(anyerror) * 8)) anyerror", - .snippet = "@intToError(${1:value: std.meta.IntType(false, @sizeOf(anyerror) * 8)})", - .documentation = - \\ Converts from the integer representation of an error into The Global Error Set type. - \\ It is generally recommended to avoid this cast, as the integer representation of an error is not stable across source code changes. - \\ Attempting to convert an integer that does not correspond to any error results in safety-protected Undefined Behavior. + .snippet = "@intToError(${1:value: std.meta.IntType(false, @sizeOf(anyerror) * 8})", + .documentation = + \\Converts from the integer representation of an error into [The Global Error Set](https://ziglang.org/documentation/0.7.1/#The-Global-Error-Set) type. + \\ + \\It is generally recommended to avoid this cast, as the integer representation of an error is not stable across source code changes. + \\ + \\Attempting to convert an integer that does not correspond to any error results in safety-protected [Undefined Behavior](https://ziglang.org/documentation/0.7.1/#Undefined-Behavior). , .arguments = &.{ - "value: std.meta.IntType(false, @sizeOf(anyerror) * 8)", + "value: std.meta.IntType(false, @sizeOf(anyerror) * 8", }, }, .{ .name = "@intToFloat", .signature = "@intToFloat(comptime DestType: type, int: anytype) DestType", .snippet = "@intToFloat(${1:comptime DestType: type}, ${2:int: anytype})", - .documentation = - \\ Converts an integer to the closest floating point representation. To convert the other way, use @floatToInt. This cast is always safe. + .documentation = + \\Converts an integer to the closest floating point representation. To convert the other way, use [@floatToInt](https://ziglang.org/documentation/0.7.1/#floatToInt). This cast is always safe. , .arguments = &.{ "comptime DestType: type", @@ -1004,9 +1009,10 @@ pub const builtins = [_]Builtin{ .name = "@intToPtr", .signature = "@intToPtr(comptime DestType: type, address: usize) DestType", .snippet = "@intToPtr(${1:comptime DestType: type}, ${2:address: usize})", - .documentation = - \\ Converts an integer to a pointer. To convert the other way, use @ptrToInt. - \\ If the destination pointer type does not allow address zero and address is zero, this invokes safety-checked Undefined Behavior. + .documentation = + \\Converts an integer to a [pointer](https://ziglang.org/documentation/0.7.1/#Pointers). To convert the other way, use [@ptrToInt](https://ziglang.org/documentation/0.7.1/#ptrToInt). + \\ + \\If the destination pointer type does not allow address zero and `address` is zero, this invokes safety-checked [Undefined Behavior](https://ziglang.org/documentation/0.7.1/#Undefined-Behavior). , .arguments = &.{ "comptime DestType: type", @@ -1017,14 +1023,16 @@ pub const builtins = [_]Builtin{ .name = "@memcpy", .signature = "@memcpy(noalias dest: [*]u8, noalias source: [*]const u8, byte_count: usize)", .snippet = "@memcpy(${1:noalias dest: [*]u8}, ${2:noalias source: [*]const u8}, ${3:byte_count: usize})", - .documentation = - \\ This function copies bytes from one region of memory to another. dest and source are both pointers and must not overlap. - \\ This function is a low level intrinsic with no safety mechanisms. Most code should not use this function, instead using something like this: - \\```zig - \\for (source[0..byte_count]) |b, i| dest[i] = b; - \\``` - \\ The optimizer is intelligent enough to turn the above snippet into a memcpy. + .documentation = + \\This function copies bytes from one region of memory to another. `dest` and `source` are both pointers and must not overlap. + \\ + \\This function is a low level intrinsic with no safety mechanisms. Most code should not use this function, instead using something like this: + \\ + \\`for (source[0..byte_count]) |b, i| dest[i] = b;` + \\The optimizer is intelligent enough to turn the above snippet into a memcpy. + \\ \\There is also a standard library function for this: + \\ \\```zig \\const mem = @import("std").mem; \\mem.copy(u8, dest[0..byte_count], source[0..byte_count]); @@ -1040,14 +1048,16 @@ pub const builtins = [_]Builtin{ .name = "@memset", .signature = "@memset(dest: [*]u8, c: u8, byte_count: usize)", .snippet = "@memset(${1:dest: [*]u8}, ${2:c: u8}, ${3:byte_count: usize})", - .documentation = - \\ This function sets a region of memory to c. dest is a pointer. - \\ This function is a low level intrinsic with no safety mechanisms. Most code should not use this function, instead using something like this: - \\```zig - \\for (dest[0..byte_count]) |*b| b.* = c; - \\``` - \\ The optimizer is intelligent enough to turn the above snippet into a memset. + .documentation = + \\This function sets a region of memory to `c`. `dest` is a pointer. + \\ + \\This function is a low level intrinsic with no safety mechanisms. Most code should not use this function, instead using something like this: + \\ + \\`for (dest[0..byte_count]) |*b| b.* = c;` + \\The optimizer is intelligent enough to turn the above snippet into a memset. + \\ \\There is also a standard library function for this: + \\ \\```zig \\const mem = @import("std").mem; \\mem.set(u8, dest, c); @@ -1063,9 +1073,10 @@ pub const builtins = [_]Builtin{ .name = "@wasmMemorySize", .signature = "@wasmMemorySize(index: u32) u32", .snippet = "@wasmMemorySize(${1:index: u32})", - .documentation = - \\ This function returns the size of the Wasm memory identified by index as an unsigned value in units of Wasm pages. Note that each Wasm page is 64KB in size. - \\ This function is a low level intrinsic with no safety mechanisms usually useful for allocator designers targeting Wasm. So unless you are writing a new allocator from scratch, you should use something like @import("std").heap.WasmPageAllocator. + .documentation = + \\This function returns the size of the Wasm memory identified by `index` as an unsigned value in units of Wasm pages. Note that each Wasm page is 64KB in size. + \\ + \\This function is a low level intrinsic with no safety mechanisms usually useful for allocator designers targeting Wasm. So unless you are writing a new allocator from scratch, you should use something like `@import("std").heap.WasmPageAllocator`. , .arguments = &.{ "index: u32", @@ -1075,29 +1086,22 @@ pub const builtins = [_]Builtin{ .name = "@wasmMemoryGrow", .signature = "@wasmMemoryGrow(index: u32, delta: u32) i32", .snippet = "@wasmMemoryGrow(${1:index: u32}, ${2:delta: u32})", - .documentation = - \\ This function increases the size of the Wasm memory identified by index by delta in units of unsigned number of Wasm pages. Note that each Wasm page is 64KB in size. On success, returns previous memory size; on failure, if the allocation fails, returns -1. - \\ This function is a low level intrinsic with no safety mechanisms usually useful for allocator designers targeting Wasm. So unless you are writing a new allocator from scratch, you should use something like @import("std").heap.WasmPageAllocator. - \\test.zig + .documentation = + \\This function increases the size of the Wasm memory identified by `index` by `delta` in units of unsigned number of Wasm pages. Note that each Wasm page is 64KB in size. On success, returns previous memory size; on failure, if the allocation fails, returns -1. + \\ + \\This function is a low level intrinsic with no safety mechanisms usually useful for allocator designers targeting Wasm. So unless you are writing a new allocator from scratch, you should use something like `@import("std").heap.WasmPageAllocator`. + \\ \\```zig \\const std = @import("std"); \\const builtin = @import("builtin"); \\const expect = std.testing.expect; - \\ \\test "@wasmMemoryGrow" { \\ if (builtin.arch != .wasm32) return error.SkipZigTest; - \\ \\ var prev = @wasmMemorySize(0); \\ expect(prev == @wasmMemoryGrow(0, 1)); \\ expect(prev + 1 == @wasmMemorySize(0)); \\} \\``` - \\```zig - \\$ zig test test.zig - \\1/1 test "@wasmMemoryGrow"... SKIP - \\0 passed; 1 skipped. - \\ - \\``` , .arguments = &.{ "index: u32", @@ -1108,8 +1112,12 @@ pub const builtins = [_]Builtin{ .name = "@mod", .signature = "@mod(numerator: T, denominator: T) T", .snippet = "@mod(${1:numerator: T}, ${2:denominator: T})", - .documentation = - \\ Modulus division. For unsigned integers this is the same as numerator % denominator. Caller guarantees denominator > 0. + .documentation = + \\Modulus division. For unsigned integers this is the same as `numerator % denominator`. Caller guarantees `denominator > 0`. + \\ + \\ - `@mod(-5, 3) == 1` + \\ - `(@divFloor(a, b) * b) + @mod(a, b) == a` + \\For a function that returns an error code, see `@import("std").math.mod`. , .arguments = &.{ "numerator: T", @@ -1120,8 +1128,8 @@ pub const builtins = [_]Builtin{ .name = "@mulWithOverflow", .signature = "@mulWithOverflow(comptime T: type, a: T, b: T, result: *T) bool", .snippet = "@mulWithOverflow(${1:comptime T: type}, ${2:a: T}, ${3:b: T}, ${4:result: *T})", - .documentation = - \\ Performs result.* = a * b. If overflow or underflow occurs, stores the overflowed bits in result and returns true. If no overflow or underflow occurs, returns false. + .documentation = + \\Performs `result.* = a * b`. If overflow or underflow occurs, stores the overflowed bits in `result` and returns `true`. If no overflow or underflow occurs, returns `false`. , .arguments = &.{ "comptime T: type", @@ -1134,9 +1142,13 @@ pub const builtins = [_]Builtin{ .name = "@panic", .signature = "@panic(message: []const u8) noreturn", .snippet = "@panic(${1:message: []const u8})", - .documentation = - \\ Invokes the panic handler function. By default the panic handler function calls the public panic function exposed in the root source file, or if there is not one specified, the std.builtin.default_panic function from std/builtin.zig. - \\Generally it is better to use @import("std").debug.panic. However, @panic can be useful for 2 scenarios: + .documentation = + \\Invokes the panic handler function. By default the panic handler function calls the public `panic` function exposed in the root source file, or if there is not one specified, the `std.builtin.default_panic` function from `std/builtin.zig`. + \\ + \\Generally it is better to use `@import("std").debug.panic`. However, `@panic` can be useful for 2 scenarios: + \\ + \\ - From library code, calling the programmer's panic function if they exposed one in the root source file. + \\ - When mixing C and Zig code, calling the canonical panic implementation across multiple .o files. , .arguments = &.{ "message: []const u8", @@ -1146,9 +1158,10 @@ pub const builtins = [_]Builtin{ .name = "@popCount", .signature = "@popCount(comptime T: type, integer: T)", .snippet = "@popCount(${1:comptime T: type}, ${2:integer: T})", - .documentation = + .documentation = \\Counts the number of bits set in an integer. - \\ If integer is known at comptime, the return type is comptime_int. Otherwise, the return type is an unsigned integer with the minimum number of bits that can represent the bit count of the integer type. + \\ + \\If `integer` is known at [comptime](https://ziglang.org/documentation/0.7.1/#comptime), the return type is `comptime_int`. Otherwise, the return type is an unsigned integer with the minimum number of bits that can represent the bit count of the integer type. , .arguments = &.{ "comptime T: type", @@ -1159,9 +1172,10 @@ pub const builtins = [_]Builtin{ .name = "@ptrCast", .signature = "@ptrCast(comptime DestType: type, value: anytype) DestType", .snippet = "@ptrCast(${1:comptime DestType: type}, ${2:value: anytype})", - .documentation = - \\ Converts a pointer of one type to a pointer of another type. - \\ Optional Pointers are allowed. Casting an optional pointer which is null to a non-optional pointer invokes safety-checked Undefined Behavior. + .documentation = + \\Converts a pointer of one type to a pointer of another type. + \\ + \\[Optional Pointers](https://ziglang.org/documentation/0.7.1/#Optional-Pointers) are allowed. Casting an optional pointer which is [null](https://ziglang.org/documentation/0.7.1/#null) to a non-optional pointer invokes safety-checked [Undefined Behavior](https://ziglang.org/documentation/0.7.1/#Undefined-Behavior). , .arguments = &.{ "comptime DestType: type", @@ -1172,8 +1186,14 @@ pub const builtins = [_]Builtin{ .name = "@ptrToInt", .signature = "@ptrToInt(value: anytype) usize", .snippet = "@ptrToInt(${1:value: anytype})", - .documentation = - \\ Converts value to a usize which is the address of the pointer. value can be one of these types: + .documentation = + \\Converts `value` to a `usize` which is the address of the pointer. `value` can be one of these types: + \\ + \\ - `*T` + \\ - `?*T` + \\ - `fn()` + \\ - `?fn()` + \\To convert the other way, use [@intToPtr](https://ziglang.org/documentation/0.7.1/#intToPtr) , .arguments = &.{ "value: anytype", @@ -1183,8 +1203,12 @@ pub const builtins = [_]Builtin{ .name = "@rem", .signature = "@rem(numerator: T, denominator: T) T", .snippet = "@rem(${1:numerator: T}, ${2:denominator: T})", - .documentation = - \\ Remainder division. For unsigned integers this is the same as numerator % denominator. Caller guarantees denominator > 0. + .documentation = + \\Remainder division. For unsigned integers this is the same as `numerator % denominator`. Caller guarantees `denominator > 0`. + \\ + \\ - `@rem(-5, 3) == -2` + \\ - `(@divTrunc(a, b) * b) + @rem(a, b) == a` + \\For a function that returns an error code, see `@import("std").math.rem`. , .arguments = &.{ "numerator: T", @@ -1195,10 +1219,12 @@ pub const builtins = [_]Builtin{ .name = "@returnAddress", .signature = "@returnAddress() usize", .snippet = "@returnAddress()", - .documentation = - \\ This function returns the address of the next machine code instruction that will be executed when the current function returns. - \\ The implications of this are target specific and not consistent across all platforms. - \\ This function is only valid within function scope. If the function gets inlined into a calling function, the returned address will apply to the calling function. + .documentation = + \\This function returns the address of the next machine code instruction that will be executed when the current function returns. + \\ + \\The implications of this are target specific and not consistent across all platforms. + \\ + \\This function is only valid within function scope. If the function gets inlined into a calling function, the returned address will apply to the calling function. , .arguments = &.{}, }, @@ -1206,8 +1232,8 @@ pub const builtins = [_]Builtin{ .name = "@setAlignStack", .signature = "@setAlignStack(comptime alignment: u29)", .snippet = "@setAlignStack(${1:comptime alignment: u29})", - .documentation = - \\ Ensures that a function will have a stack alignment of at least alignment bytes. + .documentation = + \\Ensures that a function will have a stack alignment of at least `alignment` bytes. , .arguments = &.{ "comptime alignment: u29", @@ -1217,8 +1243,8 @@ pub const builtins = [_]Builtin{ .name = "@setCold", .signature = "@setCold(is_cold: bool)", .snippet = "@setCold(${1:is_cold: bool})", - .documentation = - \\ Tells the optimizer that a function is rarely called. + .documentation = + \\Tells the optimizer that a function is rarely called. , .arguments = &.{ "is_cold: bool", @@ -1228,46 +1254,23 @@ pub const builtins = [_]Builtin{ .name = "@setEvalBranchQuota", .signature = "@setEvalBranchQuota(new_quota: u32)", .snippet = "@setEvalBranchQuota(${1:new_quota: u32})", - .documentation = - \\ Changes the maximum number of backwards branches that compile-time code execution can use before giving up and making a compile error. - \\ If the new_quota is smaller than the default quota (1000) or a previously explicitly set quota, it is ignored. - \\ Example: - \\test.zig - \\```zig - \\test "foo" { - \\ comptime { - \\ var i = 0; - \\ while (i < 1001) : (i += 1) {} + .documentation = + \\Changes the maximum number of backwards branches that compile-time code execution can use before giving up and making a compile error. + \\ + \\If the `new_quota` is smaller than the default quota (`1000`) or a previously explicitly set quota, it is ignored. + \\ + \\Example: + \\ + \\1001) : (i += 1) {} \\ } \\} \\``` - \\```zig - \\$ zig test test.zig - \\./docgen_tmp/test.zig:4:9: error: evaluation exceeded 1000 backwards branches - \\ while (i < 1001) : (i += 1) {} - \\ ^ - \\./docgen_tmp/test.zig:1:12: note: referenced here - \\test "foo" { - \\ ^ + \\Now we use `@setEvalBranchQuota`: \\ - \\``` - \\Now we use @setEvalBranchQuota: - \\test.zig - \\```zig - \\test "foo" { - \\ comptime { - \\ @setEvalBranchQuota(1001); - \\ var i = 0; - \\ while (i < 1001) : (i += 1) {} + \\1001) : (i += 1) {} \\ } \\} \\``` - \\```zig - \\$ zig test test.zig - \\1/1 test "foo"... OK - \\All 1 tests passed. - \\ - \\``` , .arguments = &.{ "new_quota: u32", @@ -1277,14 +1280,26 @@ pub const builtins = [_]Builtin{ .name = "@setFloatMode", .signature = "@setFloatMode(mode: @import(\"builtin\").FloatMode)", .snippet = "@setFloatMode(${1:mode: @import(\"builtin\").FloatMode})", - .documentation = - \\ Sets the floating point mode of the current scope. Possible values are: + .documentation = + \\Sets the floating point mode of the current scope. Possible values are: + \\ \\```zig \\pub const FloatMode = enum { \\ Strict, \\ Optimized, \\}; \\``` + \\ - `Strict` (default) - Floating point operations follow strict IEEE compliance. + \\ - `Optimized` - Floating point operations may do all of the following: + \\ - Assume the arguments and result are not NaN. Optimizations are required to retain defined behavior over NaNs, but the value of the result is undefined. + \\ - Assume the arguments and result are not +/-Inf. Optimizations are required to retain defined behavior over +/-Inf, but the value of the result is undefined. + \\ - Treat the sign of a zero argument or result as insignificant. + \\ - Use the reciprocal of an argument rather than perform division. + \\ - Perform floating-point contraction (e.g. fusing a multiply followed by an addition into a fused multiply-and-add). + \\ - Perform algebraically equivalent transformations that may change results in floating point (e.g. reassociate). + \\This is equivalent to + \\`-ffast-math`in GCC. + \\The floating point mode is inherited by child scopes, and can be overridden in any scope. You can set the floating point mode in a struct or module scope by using a comptime block. , .arguments = &.{ "mode: @import(\"builtin\").FloatMode", @@ -1294,9 +1309,9 @@ pub const builtins = [_]Builtin{ .name = "@setRuntimeSafety", .signature = "@setRuntimeSafety(safety_on: bool)", .snippet = "@setRuntimeSafety(${1:safety_on: bool})", - .documentation = - \\ Sets whether runtime safety checks are enabled for the scope that contains the function call. - \\test.zig + .documentation = + \\Sets whether runtime safety checks are enabled for the scope that contains the function call. + \\ \\```zig \\test "@setRuntimeSafety" { \\ // The builtin applies to the scope that it is called in. So here, integer overflow @@ -1309,7 +1324,6 @@ pub const builtins = [_]Builtin{ \\ @setRuntimeSafety(true); \\ var x: u8 = 255; \\ x += 1; - \\ \\ { \\ // The value can be overridden at any scope. So here integer overflow \\ // would not be caught in any build mode. @@ -1320,14 +1334,9 @@ pub const builtins = [_]Builtin{ \\ } \\} \\``` - \\```zig - \\$ zig test test.zig-OReleaseFast - \\1/1 test "@setRuntimeSafety"... integer overflow - \\error: the following test command crashed: - \\docgen_tmp/zig-cache/o/d760ff9dc12761126824676bb5d40d62/test - \\ - \\``` - \\Note: it is planned to replace @setRuntimeSafety with @optimizeFor + \\Note: it is + \\[planned](https://github.com/ziglang/zig/issues/978)to replace `@setRuntimeSafety` with + \\`@optimizeFor` , .arguments = &.{ "safety_on: bool", @@ -1337,9 +1346,10 @@ pub const builtins = [_]Builtin{ .name = "@shlExact", .signature = "@shlExact(value: T, shift_amt: Log2T) T", .snippet = "@shlExact(${1:value: T}, ${2:shift_amt: Log2T})", - .documentation = - \\ Performs the left shift operation (<<). Caller guarantees that the shift will not shift any 1 bits out. - \\ The type of shift_amt is an unsigned integer with log2(T.bit_count) bits. This is because shift_amt >= T.bit_count is undefined behavior. + .documentation = + \\`). Caller guarantees that the shift will not shift any 1 bits out. + \\ + \\The type of `shift_amt` is an unsigned integer with `log2(T.bit_count)` bits. This is because `shift_amt >= T.bit_count` is undefined behavior. , .arguments = &.{ "value: T", @@ -1350,9 +1360,10 @@ pub const builtins = [_]Builtin{ .name = "@shlWithOverflow", .signature = "@shlWithOverflow(comptime T: type, a: T, shift_amt: Log2T, result: *T) bool", .snippet = "@shlWithOverflow(${1:comptime T: type}, ${2:a: T}, ${3:shift_amt: Log2T}, ${4:result: *T})", - .documentation = - \\ Performs result.* = a << b. If overflow or underflow occurs, stores the overflowed bits in result and returns true. If no overflow or underflow occurs, returns false. - \\ The type of shift_amt is an unsigned integer with log2(T.bit_count) bits. This is because shift_amt >= T.bit_count is undefined behavior. + .documentation = + \\b`. If overflow or underflow occurs, stores the overflowed bits in `result` and returns `true`. If no overflow or underflow occurs, returns `false`. + \\ + \\The type of `shift_amt` is an unsigned integer with `log2(T.bit_count)` bits. This is because `shift_amt >= T.bit_count` is undefined behavior. , .arguments = &.{ "comptime T: type", @@ -1365,9 +1376,10 @@ pub const builtins = [_]Builtin{ .name = "@shrExact", .signature = "@shrExact(value: T, shift_amt: Log2T) T", .snippet = "@shrExact(${1:value: T}, ${2:shift_amt: Log2T})", - .documentation = - \\ Performs the right shift operation (>>). Caller guarantees that the shift will not shift any 1 bits out. - \\ The type of shift_amt is an unsigned integer with log2(T.bit_count) bits. This is because shift_amt >= T.bit_count is undefined behavior. + .documentation = + \\Performs the right shift operation (`>>`). Caller guarantees that the shift will not shift any 1 bits out. + \\ + \\The type of `shift_amt` is an unsigned integer with `log2(T.bit_count)` bits. This is because `shift_amt >= T.bit_count` is undefined behavior. , .arguments = &.{ "value: T", @@ -1378,13 +1390,18 @@ pub const builtins = [_]Builtin{ .name = "@shuffle", .signature = "@shuffle(comptime E: type, a: std.meta.Vector(a_len, E), b: std.meta.Vector(b_len, E), comptime mask: std.meta.Vector(mask_len, i32)) std.meta.Vector(mask_len, E)", .snippet = "@shuffle(${1:comptime E: type}, ${2:a: std.meta.Vector(a_len, E)}, ${3:b: std.meta.Vector(b_len, E)}, ${4:comptime mask: std.meta.Vector(mask_len, i32)})", - .documentation = - \\ Constructs a new vector by selecting elements from a and b based on mask. - \\ Each element in mask selects an element from either a or b. Positive numbers select from a starting at 0. Negative values select from b, starting at -1 and going down. It is recommended to use the ~ operator from indexes from b so that both indexes can start from 0 (i.e. ~@as(i32, 0) is -1). - \\ For each element of mask, if it or the selected value from a or b is undefined, then the resulting element is undefined. - \\ a_len and b_len may differ in length. Out-of-bounds element indexes in mask result in compile errors. - \\ If a or b is undefined, it is equivalent to a vector of all undefined with the same length as the other vector. If both vectors are undefined, @shuffle returns a vector with all elements undefined. - \\ E must be an integer, float, pointer, or bool. The mask may be any vector length, and its length determines the result length. + .documentation = + \\Constructs a new [vector](https://ziglang.org/documentation/0.7.1/#Vectors) by selecting elements from `a` and `b` based on `mask`. + \\ + \\Each element in `mask` selects an element from either `a` or `b`. Positive numbers select from `a` starting at 0. Negative values select from `b`, starting at `-1` and going down. It is recommended to use the `~` operator from indexes from `b` so that both indexes can start from `0` (i.e. `~@as(i32, 0)` is `-1`). + \\ + \\For each element of `mask`, if it or the selected value from `a` or `b` is `undefined`, then the resulting element is `undefined`. + \\ + \\`a_len` and `b_len` may differ in length. Out-of-bounds element indexes in `mask` result in compile errors. + \\ + \\If `a` or `b` is `undefined`, it is equivalent to a vector of all `undefined` with the same length as the other vector. If both vectors are `undefined`, `@shuffle` returns a vector with all elements `undefined`. + \\ + \\`E` must be an [integer](https://ziglang.org/documentation/0.7.1/#Integers), [float](https://ziglang.org/documentation/0.7.1/#Floats), [pointer](https://ziglang.org/documentation/0.7.1/#Pointers), or `bool`. The mask may be any vector length, and its length determines the result length. , .arguments = &.{ "comptime E: type", @@ -1397,10 +1414,12 @@ pub const builtins = [_]Builtin{ .name = "@sizeOf", .signature = "@sizeOf(comptime T: type) comptime_int", .snippet = "@sizeOf(${1:comptime T: type})", - .documentation = - \\ This function returns the number of bytes it takes to store T in memory. The result is a target-specific compile time constant. - \\ This size may contain padding bytes. If there were two consecutive T in memory, this would be the offset in bytes between element at index 0 and the element at index 1. For integer, consider whether you want to use @sizeOf(T) or @typeInfo(T).Int.bits. - \\ This function measures the size at runtime. For types that are disallowed at runtime, such as comptime_int and type, the result is 0. + .documentation = + \\This function returns the number of bytes it takes to store `T` in memory. The result is a target-specific compile time constant. + \\ + \\This size may contain padding bytes. If there were two consecutive T in memory, this would be the offset in bytes between element at index 0 and the element at index 1. For [integer](https://ziglang.org/documentation/0.7.1/#Integers), consider whether you want to use `@sizeOf(T)` or `@typeInfo(T).Int.bits`. + \\ + \\This function measures the size at runtime. For types that are disallowed at runtime, such as `comptime_int` and `type`, the result is `0`. , .arguments = &.{ "comptime T: type", @@ -1410,13 +1429,12 @@ pub const builtins = [_]Builtin{ .name = "@splat", .signature = "@splat(comptime len: u32, scalar: anytype) std.meta.Vector(len, @TypeOf(scalar))", .snippet = "@splat(${1:comptime len: u32}, ${2:scalar: anytype})", - .documentation = - \\ Produces a vector of length len where each element is the value scalar: - \\test.zig + .documentation = + \\Produces a vector of length `len` where each element is the value `scalar`: + \\ \\```zig \\const std = @import("std"); \\const expect = std.testing.expect; - \\ \\test "vector @splat" { \\ const scalar: u32 = 5; \\ const result = @splat(4, scalar); @@ -1424,13 +1442,7 @@ pub const builtins = [_]Builtin{ \\ expect(std.mem.eql(u32, &@as([4]u32, result), &[_]u32{ 5, 5, 5, 5 })); \\} \\``` - \\```zig - \\$ zig test test.zig - \\1/1 test "vector @splat"... OK - \\All 1 tests passed. - \\ - \\``` - \\ scalar must be an integer, bool, float, or pointer. + \\`scalar` must be an [integer](https://ziglang.org/documentation/0.7.1/#Integers), [bool](https://ziglang.org/documentation/0.7.1/#Primitive-Types), [float](https://ziglang.org/documentation/0.7.1/#Floats), or [pointer](https://ziglang.org/documentation/0.7.1/#Pointers). , .arguments = &.{ "comptime len: u32", @@ -1441,9 +1453,29 @@ pub const builtins = [_]Builtin{ .name = "@reduce", .signature = "@reduce(comptime op: builtin.ReduceOp, value: anytype) std.meta.Child(value)", .snippet = "@reduce(${1:comptime op: builtin.ReduceOp}, ${2:value: anytype})", - .documentation = - \\ Transforms a vector into a scalar value by performing a sequential horizontal reduction of its elements using the specified operator op. - \\ Not every operator is available for every vector element type: + .documentation = + \\Transforms a [vector](https://ziglang.org/documentation/0.7.1/#Vectors) into a scalar value by performing a sequential horizontal reduction of its elements using the specified operator `op`. + \\ + \\Not every operator is available for every vector element type: + \\ + \\ - `.And`, `.Or`, `.Xor` are available for `bool` vectors, + \\ - `.Min`, `.Max`, `.Add`, `.Mul` are available for [floating point](https://ziglang.org/documentation/0.7.1/#Floats) vectors, + \\ - Every operator is available for [integer](https://ziglang.org/documentation/0.7.1/#Integers) vectors. + \\Note that `.Add` and `.Mul` reductions on integral types are wrapping; when applied on floating point types the operation associativity is preserved, unless the float mode is set to `Optimized`. + \\ + \\```zig + \\const std = @import("std"); + \\const expect = std.testing.expect; + \\test "vector @reduce" { + \\ const value: std.meta.Vector(4, i32) = [_]i32{ 1, -1, 1, -1 }; + \\ const result = value > @splat(4, @as(i32, 0)); + \\ // result is { true, false, true, false }; + \\ comptime expect(@TypeOf(result) == std.meta.Vector(4, bool)); + \\ const is_all_true = @reduce(.And, result); + \\ comptime expect(@TypeOf(is_all_true) == bool); + \\ expect(is_all_true == false); + \\} + \\``` , .arguments = &.{ "comptime op: builtin.ReduceOp", @@ -1454,32 +1486,23 @@ pub const builtins = [_]Builtin{ .name = "@src", .signature = "@src() std.builtin.SourceLocation", .snippet = "@src()", - .documentation = - \\ Returns a SourceLocation struct representing the function's name and location in the source code. This must be called in a function. - \\test.zig + .documentation = + \\Returns a `SourceLocation` struct representing the function's name and location in the source code. This must be called in a function. + \\ \\```zig \\const std = @import("std"); \\const expect = std.testing.expect; - \\ \\test "@src" { \\ doTheTest(); \\} - \\ \\fn doTheTest() void { \\ const src = @src(); - \\ \\ expect(src.line == 9); \\ expect(src.column == 17); \\ expect(std.mem.endsWith(u8, src.fn_name, "doTheTest")); \\ expect(std.mem.endsWith(u8, src.file, "test.zig")); \\} \\``` - \\```zig - \\$ zig test test.zig - \\1/1 test "@src"... OK - \\All 1 tests passed. - \\ - \\``` , .arguments = &.{}, }, @@ -1487,9 +1510,11 @@ pub const builtins = [_]Builtin{ .name = "@sqrt", .signature = "@sqrt(value: anytype) @TypeOf(value)", .snippet = "@sqrt(${1:value: anytype})", - .documentation = - \\ Performs the square root of a floating point number. Uses a dedicated hardware instruction when available. - \\ Supports Floats and Vectors of floats, with the caveat that some float operations are not yet implemented for all float types. + .documentation = + \\Performs the square root of a floating point number. Uses a dedicated hardware instruction when available. + \\ + \\Supports [Floats](https://ziglang.org/documentation/0.7.1/#Floats) and [Vectors](https://ziglang.org/documentation/0.7.1/#Vectors) of floats, with the caveat that + \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). , .arguments = &.{ "value: anytype", @@ -1499,9 +1524,11 @@ pub const builtins = [_]Builtin{ .name = "@sin", .signature = "@sin(value: anytype) @TypeOf(value)", .snippet = "@sin(${1:value: anytype})", - .documentation = - \\ Sine trigometric function on a floating point number. Uses a dedicated hardware instruction when available. - \\ Supports Floats and Vectors of floats, with the caveat that some float operations are not yet implemented for all float types. + .documentation = + \\Sine trigometric function on a floating point number. Uses a dedicated hardware instruction when available. + \\ + \\Supports [Floats](https://ziglang.org/documentation/0.7.1/#Floats) and [Vectors](https://ziglang.org/documentation/0.7.1/#Vectors) of floats, with the caveat that + \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). , .arguments = &.{ "value: anytype", @@ -1511,9 +1538,11 @@ pub const builtins = [_]Builtin{ .name = "@cos", .signature = "@cos(value: anytype) @TypeOf(value)", .snippet = "@cos(${1:value: anytype})", - .documentation = - \\ Cosine trigometric function on a floating point number. Uses a dedicated hardware instruction when available. - \\ Supports Floats and Vectors of floats, with the caveat that some float operations are not yet implemented for all float types. + .documentation = + \\Cosine trigometric function on a floating point number. Uses a dedicated hardware instruction when available. + \\ + \\Supports [Floats](https://ziglang.org/documentation/0.7.1/#Floats) and [Vectors](https://ziglang.org/documentation/0.7.1/#Vectors) of floats, with the caveat that + \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). , .arguments = &.{ "value: anytype", @@ -1523,9 +1552,11 @@ pub const builtins = [_]Builtin{ .name = "@exp", .signature = "@exp(value: anytype) @TypeOf(value)", .snippet = "@exp(${1:value: anytype})", - .documentation = - \\ Base-e exponential function on a floating point number. Uses a dedicated hardware instruction when available. - \\ Supports Floats and Vectors of floats, with the caveat that some float operations are not yet implemented for all float types. + .documentation = + \\Base-e exponential function on a floating point number. Uses a dedicated hardware instruction when available. + \\ + \\Supports [Floats](https://ziglang.org/documentation/0.7.1/#Floats) and [Vectors](https://ziglang.org/documentation/0.7.1/#Vectors) of floats, with the caveat that + \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). , .arguments = &.{ "value: anytype", @@ -1535,9 +1566,11 @@ pub const builtins = [_]Builtin{ .name = "@exp2", .signature = "@exp2(value: anytype) @TypeOf(value)", .snippet = "@exp2(${1:value: anytype})", - .documentation = - \\ Base-2 exponential function on a floating point number. Uses a dedicated hardware instruction when available. - \\ Supports Floats and Vectors of floats, with the caveat that some float operations are not yet implemented for all float types. + .documentation = + \\Base-2 exponential function on a floating point number. Uses a dedicated hardware instruction when available. + \\ + \\Supports [Floats](https://ziglang.org/documentation/0.7.1/#Floats) and [Vectors](https://ziglang.org/documentation/0.7.1/#Vectors) of floats, with the caveat that + \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). , .arguments = &.{ "value: anytype", @@ -1547,9 +1580,11 @@ pub const builtins = [_]Builtin{ .name = "@log", .signature = "@log(value: anytype) @TypeOf(value)", .snippet = "@log(${1:value: anytype})", - .documentation = - \\ Returns the natural logarithm of a floating point number. Uses a dedicated hardware instruction when available. - \\ Supports Floats and Vectors of floats, with the caveat that some float operations are not yet implemented for all float types. + .documentation = + \\Returns the natural logarithm of a floating point number. Uses a dedicated hardware instruction when available. + \\ + \\Supports [Floats](https://ziglang.org/documentation/0.7.1/#Floats) and [Vectors](https://ziglang.org/documentation/0.7.1/#Vectors) of floats, with the caveat that + \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). , .arguments = &.{ "value: anytype", @@ -1559,9 +1594,11 @@ pub const builtins = [_]Builtin{ .name = "@log2", .signature = "@log2(value: anytype) @TypeOf(value)", .snippet = "@log2(${1:value: anytype})", - .documentation = - \\ Returns the logarithm to the base 2 of a floating point number. Uses a dedicated hardware instruction when available. - \\ Supports Floats and Vectors of floats, with the caveat that some float operations are not yet implemented for all float types. + .documentation = + \\Returns the logarithm to the base 2 of a floating point number. Uses a dedicated hardware instruction when available. + \\ + \\Supports [Floats](https://ziglang.org/documentation/0.7.1/#Floats) and [Vectors](https://ziglang.org/documentation/0.7.1/#Vectors) of floats, with the caveat that + \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). , .arguments = &.{ "value: anytype", @@ -1571,9 +1608,11 @@ pub const builtins = [_]Builtin{ .name = "@log10", .signature = "@log10(value: anytype) @TypeOf(value)", .snippet = "@log10(${1:value: anytype})", - .documentation = - \\ Returns the logarithm to the base 10 of a floating point number. Uses a dedicated hardware instruction when available. - \\ Supports Floats and Vectors of floats, with the caveat that some float operations are not yet implemented for all float types. + .documentation = + \\Returns the logarithm to the base 10 of a floating point number. Uses a dedicated hardware instruction when available. + \\ + \\Supports [Floats](https://ziglang.org/documentation/0.7.1/#Floats) and [Vectors](https://ziglang.org/documentation/0.7.1/#Vectors) of floats, with the caveat that + \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). , .arguments = &.{ "value: anytype", @@ -1583,9 +1622,11 @@ pub const builtins = [_]Builtin{ .name = "@fabs", .signature = "@fabs(value: anytype) @TypeOf(value)", .snippet = "@fabs(${1:value: anytype})", - .documentation = - \\ Returns the absolute value of a floating point number. Uses a dedicated hardware instruction when available. - \\ Supports Floats and Vectors of floats, with the caveat that some float operations are not yet implemented for all float types. + .documentation = + \\Returns the absolute value of a floating point number. Uses a dedicated hardware instruction when available. + \\ + \\Supports [Floats](https://ziglang.org/documentation/0.7.1/#Floats) and [Vectors](https://ziglang.org/documentation/0.7.1/#Vectors) of floats, with the caveat that + \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). , .arguments = &.{ "value: anytype", @@ -1595,9 +1636,11 @@ pub const builtins = [_]Builtin{ .name = "@floor", .signature = "@floor(value: anytype) @TypeOf(value)", .snippet = "@floor(${1:value: anytype})", - .documentation = - \\ Returns the largest integral value not greater than the given floating point number. Uses a dedicated hardware instruction when available. - \\ Supports Floats and Vectors of floats, with the caveat that some float operations are not yet implemented for all float types. + .documentation = + \\Returns the largest integral value not greater than the given floating point number. Uses a dedicated hardware instruction when available. + \\ + \\Supports [Floats](https://ziglang.org/documentation/0.7.1/#Floats) and [Vectors](https://ziglang.org/documentation/0.7.1/#Vectors) of floats, with the caveat that + \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). , .arguments = &.{ "value: anytype", @@ -1607,9 +1650,11 @@ pub const builtins = [_]Builtin{ .name = "@ceil", .signature = "@ceil(value: anytype) @TypeOf(value)", .snippet = "@ceil(${1:value: anytype})", - .documentation = - \\ Returns the largest integral value not less than the given floating point number. Uses a dedicated hardware instruction when available. - \\ Supports Floats and Vectors of floats, with the caveat that some float operations are not yet implemented for all float types. + .documentation = + \\Returns the largest integral value not less than the given floating point number. Uses a dedicated hardware instruction when available. + \\ + \\Supports [Floats](https://ziglang.org/documentation/0.7.1/#Floats) and [Vectors](https://ziglang.org/documentation/0.7.1/#Vectors) of floats, with the caveat that + \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). , .arguments = &.{ "value: anytype", @@ -1619,9 +1664,11 @@ pub const builtins = [_]Builtin{ .name = "@trunc", .signature = "@trunc(value: anytype) @TypeOf(value)", .snippet = "@trunc(${1:value: anytype})", - .documentation = - \\ Rounds the given floating point number to an integer, towards zero. Uses a dedicated hardware instruction when available. - \\ Supports Floats and Vectors of floats, with the caveat that some float operations are not yet implemented for all float types. + .documentation = + \\Rounds the given floating point number to an integer, towards zero. Uses a dedicated hardware instruction when available. + \\ + \\Supports [Floats](https://ziglang.org/documentation/0.7.1/#Floats) and [Vectors](https://ziglang.org/documentation/0.7.1/#Vectors) of floats, with the caveat that + \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). , .arguments = &.{ "value: anytype", @@ -1631,9 +1678,11 @@ pub const builtins = [_]Builtin{ .name = "@round", .signature = "@round(value: anytype) @TypeOf(value)", .snippet = "@round(${1:value: anytype})", - .documentation = - \\ Rounds the given floating point number to an integer, away from zero. Uses a dedicated hardware instruction when available. - \\ Supports Floats and Vectors of floats, with the caveat that some float operations are not yet implemented for all float types. + .documentation = + \\Rounds the given floating point number to an integer, away from zero. Uses a dedicated hardware instruction when available. + \\ + \\Supports [Floats](https://ziglang.org/documentation/0.7.1/#Floats) and [Vectors](https://ziglang.org/documentation/0.7.1/#Vectors) of floats, with the caveat that + \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). , .arguments = &.{ "value: anytype", @@ -1643,8 +1692,8 @@ pub const builtins = [_]Builtin{ .name = "@subWithOverflow", .signature = "@subWithOverflow(comptime T: type, a: T, b: T, result: *T) bool", .snippet = "@subWithOverflow(${1:comptime T: type}, ${2:a: T}, ${3:b: T}, ${4:result: *T})", - .documentation = - \\ Performs result.* = a - b. If overflow or underflow occurs, stores the overflowed bits in result and returns true. If no overflow or underflow occurs, returns false. + .documentation = + \\Performs `result.* = a - b`. If overflow or underflow occurs, stores the overflowed bits in `result` and returns `true`. If no overflow or underflow occurs, returns `false`. , .arguments = &.{ "comptime T: type", @@ -1657,9 +1706,10 @@ pub const builtins = [_]Builtin{ .name = "@tagName", .signature = "@tagName(value: anytype) []const u8", .snippet = "@tagName(${1:value: anytype})", - .documentation = - \\ Converts an enum value or union value to a slice of bytes representing the name. - \\If the enum is non-exhaustive and the tag value does not map to a name, it invokes safety-checked Undefined Behavior. + .documentation = + \\Converts an enum value or union value to a slice of bytes representing the name. + \\ + \\If the enum is non-exhaustive and the tag value does not map to a name, it invokes safety-checked [Undefined Behavior](https://ziglang.org/documentation/0.7.1/#Undefined-Behavior). , .arguments = &.{ "value: anytype", @@ -1669,9 +1719,10 @@ pub const builtins = [_]Builtin{ .name = "@TagType", .signature = "@TagType(T: type) type", .snippet = "@TagType(${1:T: type})", - .documentation = - \\ For an enum, returns the integer type that is used to store the enumeration value. - \\ For a union, returns the enum type that is used to store the tag value. + .documentation = + \\For an enum, returns the integer type that is used to store the enumeration value. + \\ + \\For a union, returns the enum type that is used to store the tag value. , .arguments = &.{ "T: type", @@ -1681,38 +1732,28 @@ pub const builtins = [_]Builtin{ .name = "@This", .signature = "@This() type", .snippet = "@This()", - .documentation = - \\ Returns the innermost struct, enum, or union that this function call is inside. This can be useful for an anonymous struct that needs to refer to itself: - \\test.zig + .documentation = + \\Returns the innermost struct, enum, or union that this function call is inside. This can be useful for an anonymous struct that needs to refer to itself: + \\ \\```zig \\const std = @import("std"); \\const expect = std.testing.expect; - \\ \\test "@This()" { \\ var items = [_]i32{ 1, 2, 3, 4 }; \\ const list = List(i32){ .items = items[0..] }; \\ expect(list.length() == 4); \\} - \\ \\fn List(comptime T: type) type { \\ return struct { \\ const Self = @This(); - \\ \\ items: []T, - \\ \\ fn length(self: Self) usize { \\ return self.items.len; \\ } \\ }; \\} \\``` - \\```zig - \\$ zig test test.zig - \\1/1 test "@This()"... OK - \\All 1 tests passed. - \\ - \\``` - \\ When @This() is used at global scope, it returns a reference to the struct that corresponds to the current file. + \\When `@This()` is used at global scope, it returns a reference to the struct that corresponds to the current file. , .arguments = &.{}, }, @@ -1720,54 +1761,29 @@ pub const builtins = [_]Builtin{ .name = "@truncate", .signature = "@truncate(comptime T: type, integer: anytype) T", .snippet = "@truncate(${1:comptime T: type}, ${2:integer: anytype})", - .documentation = - \\ This function truncates bits from an integer type, resulting in a smaller or same-sized integer type. - \\ The following produces safety-checked Undefined Behavior: - \\test.zig + .documentation = + \\This function truncates bits from an integer type, resulting in a smaller or same-sized integer type. + \\ + \\The following produces safety-checked [Undefined Behavior](https://ziglang.org/documentation/0.7.1/#Undefined-Behavior): + \\ \\```zig \\test "integer cast panic" { \\ var a: u16 = 0xabcd; \\ var b: u8 = @intCast(u8, a); \\} \\``` - \\```zig - \\$ zig test test.zig - \\1/1 test "integer cast panic"... integer cast truncated bits - \\/home/andy/Downloads/zig/docgen_tmp/test.zig:3:17: 0x205995 in test "integer cast panic" (test) - \\ var b: u8 = @intCast(u8, a); - \\ ^ - \\/home/andy/Downloads/zig/lib/std/special/test_runner.zig:61:28: 0x22dab1 in std.special.main (test) - \\ } else test_fn.func(); - \\ ^ - \\/home/andy/Downloads/zig/lib/std/start.zig:334:37: 0x20729d in std.start.posixCallMainAndExit (test) - \\ const result = root.main() catch |err| { - \\ ^ - \\/home/andy/Downloads/zig/lib/std/start.zig:162:5: 0x206fd2 in std.start._start (test) - \\ @call(.{ .modifier = .never_inline }, posixCallMainAndExit, .{}); - \\ ^ - \\error: the following test command crashed: - \\docgen_tmp/zig-cache/o/8fe80128a94c1613e48317295fc76cfc/test + \\However this is well defined and working code: \\ - \\``` - \\ However this is well defined and working code: - \\truncate.zig \\```zig \\const std = @import("std"); \\const expect = std.testing.expect; - \\ \\test "integer truncation" { \\ var a: u16 = 0xabcd; \\ var b: u8 = @truncate(u8, a); \\ expect(b == 0xcd); \\} \\``` - \\```zig - \\$ zig test truncate.zig - \\1/1 test "integer truncation"... OK - \\All 1 tests passed. - \\ - \\``` - \\ This function always truncates the significant bits of the integer, regardless of endianness on the target platform. + \\This function always truncates the significant bits of the integer, regardless of endianness on the target platform. , .arguments = &.{ "comptime T: type", @@ -1778,9 +1794,38 @@ pub const builtins = [_]Builtin{ .name = "@Type", .signature = "@Type(comptime info: @import(\"builtin\").TypeInfo) type", .snippet = "@Type(${1:comptime info: @import(\"builtin\").TypeInfo})", - .documentation = - \\ This function is the inverse of @typeInfo. It reifies type information into a type. - \\ It is available for the following types: + .documentation = + \\This function is the inverse of [@typeInfo](https://ziglang.org/documentation/0.7.1/#typeInfo). It reifies type information into a `type`. + \\ + \\It is available for the following types: + \\ + \\ - `type` + \\ - `noreturn` + \\ - `void` + \\ - `bool` + \\ - [Integers](https://ziglang.org/documentation/0.7.1/#Integers) - The maximum bit count for an integer type is `65535`. + \\ - [Floats](https://ziglang.org/documentation/0.7.1/#Floats) + \\ - [Pointers](https://ziglang.org/documentation/0.7.1/#Pointers) + \\ - `comptime_int` + \\ - `comptime_float` + \\ - `@TypeOf(undefined)` + \\ - `@TypeOf(null)` + \\ - [Arrays](https://ziglang.org/documentation/0.7.1/#Arrays) + \\ - [Optionals](https://ziglang.org/documentation/0.7.1/#Optionals) + \\ - [Error Set Type](https://ziglang.org/documentation/0.7.1/#Error-Set-Type) + \\ - [Error Union Type](https://ziglang.org/documentation/0.7.1/#Error-Union-Type) + \\ - [Vectors](https://ziglang.org/documentation/0.7.1/#Vectors) + \\ - [opaque](https://ziglang.org/documentation/0.7.1/#opaque) + \\ - [@Frame](https://ziglang.org/documentation/0.7.1/#Frame) + \\ - `anyframe` + \\ - [struct](https://ziglang.org/documentation/0.7.1/#struct) + \\ - [enum](https://ziglang.org/documentation/0.7.1/#enum) + \\ - [Enum Literals](https://ziglang.org/documentation/0.7.1/#Enum-Literals) + \\ - [union](https://ziglang.org/documentation/0.7.1/#union) + \\For these types, `@Type` is not available: + \\ + \\ - [Functions](https://ziglang.org/documentation/0.7.1/#Functions) + \\ - BoundFn , .arguments = &.{ "comptime info: @import(\"builtin\").TypeInfo", @@ -1790,9 +1835,10 @@ pub const builtins = [_]Builtin{ .name = "@typeInfo", .signature = "@typeInfo(comptime T: type) @import(\"std\").builtin.TypeInfo", .snippet = "@typeInfo(${1:comptime T: type})", - .documentation = - \\ Provides type reflection. - \\ For structs, unions, enums, and error sets, the fields are guaranteed to be in the same order as declared. For declarations, the order is unspecified. + .documentation = + \\Provides type reflection. + \\ + \\For [structs](https://ziglang.org/documentation/0.7.1/#struct), [unions](https://ziglang.org/documentation/0.7.1/#union), [enums](https://ziglang.org/documentation/0.7.1/#enum), and [error sets](https://ziglang.org/documentation/0.7.1/#Error-Set-Type), the fields are guaranteed to be in the same order as declared. For declarations, the order is unspecified. , .arguments = &.{ "comptime T: type", @@ -1802,8 +1848,8 @@ pub const builtins = [_]Builtin{ .name = "@typeName", .signature = "@typeName(T: type) [N]u8", .snippet = "@typeName(${1:T: type})", - .documentation = - \\ This function returns the string representation of a type, as an array. It is equivalent to a string literal of the type name. + .documentation = + \\This function returns the string representation of a type, as an array. It is equivalent to a string literal of the type name. , .arguments = &.{ "T: type", @@ -1813,32 +1859,26 @@ pub const builtins = [_]Builtin{ .name = "@TypeOf", .signature = "@TypeOf(...) type", .snippet = "@TypeOf(${1:...})", - .documentation = - \\ @TypeOf is a special builtin function that takes any (nonzero) number of expressions as parameters and returns the type of the result, using Peer Type Resolution. - \\ The expressions are evaluated, however they are guaranteed to have no runtime side-effects: - \\test.zig + .documentation = + \\`@TypeOf` is a special builtin function that takes any (nonzero) number of expressions as parameters and returns the type of the result, using [Peer Type Resolution](https://ziglang.org/documentation/0.7.1/#Peer-Type-Resolution). + \\ + \\The expressions are evaluated, however they are guaranteed to have no + \\**runtime** side-effects: + \\ \\```zig \\const std = @import("std"); \\const expect = std.testing.expect; - \\ \\test "no runtime side effects" { \\ var data: i32 = 0; \\ const T = @TypeOf(foo(i32, &data)); \\ comptime expect(T == i32); \\ expect(data == 0); \\} - \\ \\fn foo(comptime T: type, ptr: *T) T { \\ ptr.* += 1; \\ return ptr.*; \\} \\``` - \\```zig - \\$ zig test test.zig - \\1/1 test "no runtime side effects"... OK - \\All 1 tests passed. - \\ - \\``` , .arguments = &.{ "...", @@ -1848,9 +1888,10 @@ pub const builtins = [_]Builtin{ .name = "@unionInit", .signature = "@unionInit(comptime Union: type, comptime active_field_name: []const u8, init_expr) Union", .snippet = "@unionInit(${1:comptime Union: type}, ${2:comptime active_field_name: []const u8}, ${3:init_expr})", - .documentation = - \\ This is the same thing as union initialization syntax, except that the field name is a comptime-known value rather than an identifier token. - \\ @unionInit forwards its result location to init_expr. + .documentation = + \\This is the same thing as [union](https://ziglang.org/documentation/0.7.1/#union) initialization syntax, except that the field name is a [comptime](https://ziglang.org/documentation/0.7.1/#comptime)-known value rather than an identifier token. + \\ + \\`@unionInit` forwards its [result location](https://ziglang.org/documentation/0.7.1/#Result-Location-Semantics) to `init_expr`. , .arguments = &.{ "comptime Union: type", @@ -1859,3 +1900,5 @@ pub const builtins = [_]Builtin{ }, }, }; + +// DO NOT EDIT diff --git a/src/data/0.8.0.zig b/src/data/0.8.0.zig index 6c1a8a7..a2da3f1 100644 --- a/src/data/0.8.0.zig +++ b/src/data/0.8.0.zig @@ -1,3 +1,8 @@ +//! DO NOT EDIT +//! If you want to update this file run: +//! `zig build gen -- --generate-version-data 0.8.0` (requires an internet connection) +//! GENERATED BY src/config_gen/config_gen.zig + const Builtin = struct { name: []const u8, signature: []const u8, @@ -28,7 +33,7 @@ pub const builtins = [_]Builtin{ .documentation = \\`ptr` can be `*T`, `fn()`, `?*T`, `?fn()`, or `[]T`. It returns the same type as `ptr` except with the alignment adjusted to the new value. \\ - \\A [pointer alignment safety check](https://ziglang.org/documentation/master/#Incorrect-Pointer-Alignment) is added to the generated code to make sure the pointer is aligned as promised. + \\A [pointer alignment safety check](https://ziglang.org/documentation/0.8.0/#Incorrect-Pointer-Alignment) is added to the generated code to make sure the pointer is aligned as promised. , .arguments = &.{ "comptime alignment: u29", @@ -48,8 +53,7 @@ pub const builtins = [_]Builtin{ \\ assert(*u32 == *align(@alignOf(u32)) u32); \\} \\``` - \\ - \\The result is a target-specific compile time constant. It is guaranteed to be less than or equal to [@sizeOf(T)](https://ziglang.org/documentation/master/#@sizeOf). + \\The result is a target-specific compile time constant. It is guaranteed to be less than or equal to [@sizeOf(T)](https://ziglang.org/documentation/0.8.0/#sizeOf). , .arguments = &.{ "comptime T: type", @@ -60,7 +64,7 @@ pub const builtins = [_]Builtin{ .signature = "@as(comptime T: type, expression) T", .snippet = "@as(${1:comptime T: type}, ${2:expression})", .documentation = - \\Performs [Type Coercion](https://ziglang.org/documentation/master/#Type-Coercion). This cast is allowed when the conversion is unambiguous and safe, and is the preferred way to convert between types, whenever possible. + \\Performs [Type Coercion](https://ziglang.org/documentation/0.8.0/#Type-Coercion). This cast is allowed when the conversion is unambiguous and safe, and is the preferred way to convert between types, whenever possible. , .arguments = &.{ "comptime T: type", @@ -70,19 +74,38 @@ pub const builtins = [_]Builtin{ .{ .name = "@asyncCall", .signature = "@asyncCall(frame_buffer: []align(@alignOf(@Frame(anyAsyncFunction))) u8, result_ptr, function_ptr, args: anytype) anyframe->T", - .snippet = "@asyncCall(${1:frame_buffer: []align(@alignOf(@Frame(anyAsyncFunction))) u8}, ${2:result_ptr}, ${3:function_ptr}, ${4:args: anytype})", + .snippet = "@asyncCall(${1:frame_buffer: []align(@alignOf(@Frame(anyAsyncFunction)})", .documentation = - \\`@asyncCall` performs an `async` call on a function pointer, which may or may not be an [async function](https://ziglang.org/documentation/master/#Async-Functions). + \\`@asyncCall` performs an `async` call on a function pointer, which may or may not be an [async function](https://ziglang.org/documentation/0.8.0/#Async-Functions). \\ - \\The provided `frame_buffer` must be large enough to fit the entire function frame. This size can be determined with [@frameSize](https://ziglang.org/documentation/master/#frameSize). To provide a too-small buffer invokes safety-checked [Undefined Behavior](https://ziglang.org/documentation/master/#Undefined-Behavior). + \\The provided `frame_buffer` must be large enough to fit the entire function frame. This size can be determined with [@frameSize](https://ziglang.org/documentation/0.8.0/#frameSize). To provide a too-small buffer invokes safety-checked [Undefined Behavior](https://ziglang.org/documentation/0.8.0/#Undefined-Behavior). \\ - \\`result_ptr` is optional ([null](https://ziglang.org/documentation/master/#null) may be provided). If provided, the function call will write its result directly to the result pointer, which will be available to read after [await](https://ziglang.org/documentation/master/#Async-and-Await) completes. Any result location provided to `await` will copy the result from `result_ptr`.

{#code_begin|test|async_struct_field_fn_pointer#} const std = @import("std"); const expect = std.testing.expect; test "async fn pointer in a struct field" { var data: i32 = 1; const Foo = struct { bar: fn (*i32) callconv(.Async) void, }; var foo = Foo{ .bar = func }; var bytes: [64]u8 align(@alignOf(@Frame(func))) = undefined; const f = @asyncCall(&bytes, {}, foo.bar, .{&data}); try expect(data == 2); resume f; try expect(data == 4); } fn func(y: *i32) void { defer y.* += 2; y.* += 1; suspend {} }`
+        \\`result_ptr` is optional ([null](https://ziglang.org/documentation/0.8.0/#null) may be provided). If provided, the function call will write its result directly to the result pointer, which will be available to read after [await](https://ziglang.org/documentation/0.8.0/#Async-and-Await) completes. Any result location provided to `await` will copy the result from `result_ptr`.
+        \\
+        \\```zig
+        \\const std = @import("std");
+        \\const expect = std.testing.expect;
+        \\test "async fn pointer in a struct field" {
+        \\    var data: i32 = 1;
+        \\    const Foo = struct {
+        \\        bar: fn (*i32) callconv(.Async) void,
+        \\    };
+        \\    var foo = Foo{ .bar = func };
+        \\    var bytes: [64]u8 align(@alignOf(@Frame(func))) = undefined;
+        \\    const f = @asyncCall(&bytes, {}, foo.bar, .{&data});
+        \\    try expect(data == 2);
+        \\    resume f;
+        \\    try expect(data == 4);
+        \\}
+        \\fn func(y: *i32) void {
+        \\    defer y.* += 2;
+        \\    y.* += 1;
+        \\    suspend {}
+        \\}
+        \\```
         ,
         .arguments = &.{
-            "frame_buffer: []align(@alignOf(@Frame(anyAsyncFunction))) u8",
-            "result_ptr",
-            "function_ptr",
-            "args: anytype",
+            "frame_buffer: []align(@alignOf(@Frame(anyAsyncFunction)",
         },
     },
     .{
@@ -110,15 +133,16 @@ pub const builtins = [_]Builtin{
         \\`T` must be a pointer, a `bool`, a float, an integer or an enum.
         \\
         \\Supported operations:
-        \\  - `.Xchg` - stores the operand unmodified. Supports enums, integers and floats.
-        \\  - `.Add` - for integers, twos complement wraparound addition. Also supports [Floats](https://ziglang.org/documentation/master/#Floats).
-        \\  - `.Sub` - for integers, twos complement wraparound subtraction. Also supports [Floats](https://ziglang.org/documentation/master/#Floats).
-        \\  - `.And` - bitwise and
-        \\  - `.Nand` - bitwise nand
-        \\  - `.Or` - bitwise or
-        \\  - `.Xor` - bitwise xor
-        \\  - `.Max` - stores the operand if it is larger. Supports integers and floats.
-        \\  - `.Min` - stores the operand if it is smaller. Supports integers and floats.
+        \\
+        \\ - `.Xchg` - stores the operand unmodified. Supports enums, integers and floats.
+        \\ - `.Add` - for integers, twos complement wraparound addition. Also supports [Floats](https://ziglang.org/documentation/0.8.0/#Floats).
+        \\ - `.Sub` - for integers, twos complement wraparound subtraction. Also supports [Floats](https://ziglang.org/documentation/0.8.0/#Floats).
+        \\ - `.And` - bitwise and
+        \\ - `.Nand` - bitwise nand
+        \\ - `.Or` - bitwise or
+        \\ - `.Xor` - bitwise xor
+        \\ - `.Max` - stores the operand if it is larger. Supports integers and floats.
+        \\ - `.Min` - stores the operand if it is smaller. Supports integers and floats.
         ,
         .arguments = &.{
             "comptime T: type",
@@ -156,9 +180,9 @@ pub const builtins = [_]Builtin{
         \\Asserts that `@typeInfo(DestType) != .Pointer`. Use `@ptrCast` or `@intToPtr` if you need this.
         \\
         \\Can be used for these things for example:
-        \\  - Convert `f32` to `u32` bits
-        \\  - Convert `i32` to `u32` preserving twos complement
         \\
+        \\ - Convert `f32` to `u32` bits
+        \\ - Convert `i32` to `u32` preserving twos complement
         \\Works at compile-time if `value` is known at compile time. It's a compile error to bitcast a struct to a scalar type of the same size since structs have undefined layout. However if the struct is packed then it works.
         ,
         .arguments = &.{
@@ -173,7 +197,7 @@ pub const builtins = [_]Builtin{
         .documentation =
         \\Returns the bit offset of a field relative to its containing struct.
         \\
-        \\For non [packed structs](https://ziglang.org/documentation/master/#packed-struct), this will always be divisible by `8`. For packed structs, non-byte-aligned fields will share a byte offset, but they will have different bit offsets.
+        \\For non [packed structs](https://ziglang.org/documentation/0.8.0/#packed-struct), this will always be divisible by `8`. For packed structs, non-byte-aligned fields will share a byte offset, but they will have different bit offsets.
         ,
         .arguments = &.{
             "comptime T: type",
@@ -185,7 +209,7 @@ pub const builtins = [_]Builtin{
         .signature = "@boolToInt(value: bool) u1",
         .snippet = "@boolToInt(${1:value: bool})",
         .documentation =
-        \\Converts `true` to `@as(u1, 1)` and `false` to `@as(u1, 0)`.
+        \\Converts `true` to `u1(1)` and `false` to `u1(0)`.
         \\
         \\If the value is known at compile-time, the return type is `comptime_int` instead of `u1`.
         ,
@@ -198,7 +222,7 @@ pub const builtins = [_]Builtin{
         .signature = "@bitSizeOf(comptime T: type) comptime_int",
         .snippet = "@bitSizeOf(${1:comptime T: type})",
         .documentation =
-        \\This function returns the number of bits it takes to store `T` in memory if the type were a field in a packed struct/union. The result is a target-specific compile time constant.
+        \\This function returns the number of bits it takes to store `T` in memory. The result is a target-specific compile time constant.
         \\
         \\This function measures the size at runtime. For types that are disallowed at runtime, such as `comptime_int` and `type`, the result is `0`.
         ,
@@ -240,11 +264,11 @@ pub const builtins = [_]Builtin{
         .documentation =
         \\`T` must be an integer type with bit count evenly divisible by 8.
         \\
-        \\`operand` may be an [integer](https://ziglang.org/documentation/master/#Integers) or [vector](https://ziglang.org/documentation/master/#Vectors).
+        \\`operand` may be an [integer](https://ziglang.org/documentation/0.8.0/#Integers) or [vector](https://ziglang.org/documentation/0.8.0/#Vectors).
         \\
         \\Swaps the byte order of the integer. This converts a big endian integer to a little endian integer, and converts a little endian integer to a big endian integer.
         \\
-        \\Note that for the purposes of memory layout with respect to endianness, the integer type should be related to the number of bytes reported by [@sizeOf](https://ziglang.org/documentation/master/#sizeOf) bytes. This is demonstrated with `u24`. `@sizeOf(u24) == 4`, which means that a `u24` stored in memory takes 4 bytes, and those 4 bytes are what are swapped on a little vs big endian system. On the other hand, if `T` is specified to be `u24`, then only 3 bytes are reversed.
+        \\Note that for the purposes of memory layout with respect to endianness, the integer type should be related to the number of bytes reported by [@sizeOf](https://ziglang.org/documentation/0.8.0/#sizeOf) bytes. This is demonstrated with `u24`. `@sizeOf(u24) == 4`, which means that a `u24` stored in memory takes 4 bytes, and those 4 bytes are what are swapped on a little vs big endian system. On the other hand, if `T` is specified to be `u24`, then only 3 bytes are reversed.
         ,
         .arguments = &.{
             "comptime T: type",
@@ -268,9 +292,9 @@ pub const builtins = [_]Builtin{
         },
     },
     .{
-        .name = "@offsetOf",
-        .signature = "@offsetOf(comptime T: type, comptime field_name: []const u8) comptime_int",
-        .snippet = "@offsetOf(${1:comptime T: type}, ${2:comptime field_name: []const u8})",
+        .name = "@byteOffsetOf",
+        .signature = "@byteOffsetOf(comptime T: type, comptime field_name: []const u8) comptime_int",
+        .snippet = "@byteOffsetOf(${1:comptime T: type}, ${2:comptime field_name: []const u8})",
         .documentation =
         \\Returns the byte offset of a field relative to its containing struct.
         ,
@@ -288,17 +312,47 @@ pub const builtins = [_]Builtin{
         \\
         \\```zig
         \\const expect = @import("std").testing.expect;
-        \\
         \\test "noinline function call" {
         \\    try expect(@call(.{}, add, .{3, 9}) == 12);
         \\}
-        \\
         \\fn add(a: i32, b: i32) i32 {
         \\    return a + b;
         \\}
         \\```
+        \\`@call` allows more flexibility than normal function call syntax does. The `CallOptions` struct is reproduced here:
         \\
-        \\`@call` allows more flexibility than normal function call syntax does. The `CallOptions` struct is reproduced here:

{#syntax_block|zig|builtin.CallOptions struct#} pub const CallOptions = struct { modifier: Modifier = .auto, /// Only valid when `Modifier` is `Modifier.async_kw`. stack: ?[]align(std.Target.stack_align) u8 = null, pub const Modifier = enum { /// Equivalent to function call syntax. auto, /// Equivalent to async keyword used with function call syntax. async_kw, /// Prevents tail call optimization. This guarantees that the return /// address will point to the callsite, as opposed to the callsite's /// callsite. If the call is otherwise required to be tail-called /// or inlined, a compile error is emitted instead. never_tail, /// Guarantees that the call will not be inlined. If the call is /// otherwise required to be inlined, a compile error is emitted instead. never_inline, /// Asserts that the function call will not suspend. This allows a /// non-async function to call an async function. no_async, /// Guarantees that the call will be generated with tail call optimization. /// If this is not possible, a compile error is emitted instead. always_tail, /// Guarantees that the call will inlined at the callsite. /// If this is not possible, a compile error is emitted instead. always_inline, /// Evaluates the call at compile-time. If the call cannot be completed at /// compile-time, a compile error is emitted instead. compile_time, }; }; {#end_syntax_block#} + \\```zig + \\pub const CallOptions = struct { + \\ modifier: Modifier = .auto, + \\ stack: ?[]align(std.Target.stack_align) u8 = null, + \\ pub const Modifier = enum { + \\ /// Equivalent to function call syntax. + \\ auto, + \\ /// Equivalent to async keyword used with function call syntax. + \\ async_kw, + \\ /// Prevents tail call optimization. This guarantees that the return + \\ /// address will point to the callsite, as opposed to the callsite's + \\ /// callsite. If the call is otherwise required to be tail-called + \\ /// or inlined, a compile error is emitted instead. + \\ never_tail, + \\ /// Guarantees that the call will not be inlined. If the call is + \\ /// otherwise required to be inlined, a compile error is emitted instead. + \\ never_inline, + \\ /// Asserts that the function call will not suspend. This allows a + \\ /// non-async function to call an async function. + \\ no_async, + \\ /// Guarantees that the call will be generated with tail call optimization. + \\ /// If this is not possible, a compile error is emitted instead. + \\ always_tail, + \\ /// Guarantees that the call will inlined at the callsite. + \\ /// If this is not possible, a compile error is emitted instead. + \\ always_inline, + \\ /// Evaluates the call at compile-time. If the call cannot be completed at + \\ /// compile-time, a compile error is emitted instead. + \\ compile_time, + \\ }; + \\}; + \\``` , .arguments = &.{ "options: std.builtin.CallOptions", @@ -313,15 +367,14 @@ pub const builtins = [_]Builtin{ .documentation = \\This function can only occur inside `@cImport`. \\ - \\This appends `#define $name $value` to the `@cImport` temporary buffer. + \\This appends + \\`#define $name $value`to the `@cImport` temporary buffer. \\ - \\To define without a value, like this:`#define _GNU_SOURCE` + \\To define without a value, like this: \\ - \\Use the void value, like this: + \\`#define _GNU_SOURCE`Use the void value, like this: \\ - \\```zig - \\@cDefine("_GNU_SOURCE", {}) - \\``` + \\`@cDefine("_GNU_SOURCE", {})` , .arguments = &.{ "comptime name: []u8", @@ -340,8 +393,9 @@ pub const builtins = [_]Builtin{ \\Usually you should only have one `@cImport` in your entire application, because it saves the compiler from invoking clang multiple times, and prevents inline functions from being duplicated. \\ \\Reasons for having multiple `@cImport` expressions would be: - \\ - To avoid a symbol collision, for example if foo.h and bar.h both `#define CONNECTION_COUNT` - \\ - To analyze the C code with different preprocessor defines + \\ + \\ - To avoid a symbol collision, for example if foo.h and bar.h both + \\`#define CONNECTION_COUNT` - To analyze the C code with different preprocessor defines , .arguments = &.{ "expression", @@ -354,7 +408,8 @@ pub const builtins = [_]Builtin{ .documentation = \\This function can only occur inside `@cImport`. \\ - \\This appends `#include <$path>\n` to the `c_import` temporary buffer. + \\This appends + \\`#include <$path>\n`to the `c_import` temporary buffer. , .arguments = &.{ "comptime path: []u8", @@ -362,22 +417,18 @@ pub const builtins = [_]Builtin{ }, .{ .name = "@clz", - .signature = "@clz(comptime T: type, operand: T)", - .snippet = "@clz(${1:comptime T: type}, ${2:operand: T})", + .signature = "@clz(comptime T: type, integer: T)", + .snippet = "@clz(${1:comptime T: type}, ${2:integer: T})", .documentation = - \\`T` must be an integer type. + \\This function counts the number of most-significant (leading in a big-Endian sense) zeroes in `integer`. \\ - \\`operand` may be an [integer](https://ziglang.org/documentation/master/#Integers) or [vector](https://ziglang.org/documentation/master/#Vectors). + \\If `integer` is known at [comptime](https://ziglang.org/documentation/0.8.0/#comptime), the return type is `comptime_int`. Otherwise, the return type is an unsigned integer with the minimum number of bits that can represent the bit count of the integer type. \\ - \\This function counts the number of most-significant (leading in a big-Endian sense) zeroes in an integer. - \\ - \\If `operand` is a [comptime](https://ziglang.org/documentation/master/#comptime)-known integer, the return type is `comptime_int`. Otherwise, the return type is an unsigned integer or vector of unsigned integers with the minimum number of bits that can represent the bit count of the integer type. - \\ - \\If `operand` is zero, `@clz` returns the bit width of integer type `T`. + \\If `integer` is zero, `@clz` returns the bit width of integer type `T`. , .arguments = &.{ "comptime T: type", - "operand: T", + "integer: T", }, }, .{ @@ -398,8 +449,7 @@ pub const builtins = [_]Builtin{ \\ } \\} \\``` - \\ - \\If you are using cmpxchg in a loop, [@cmpxchgWeak](https://ziglang.org/documentation/master/#cmpxchgWeak) is the better choice, because it can be implemented more efficiently in machine instructions. + \\If you are using cmpxchg in a loop, [@cmpxchgWeak](https://ziglang.org/documentation/0.8.0/#cmpxchgWeak) is the better choice, because it can be implemented more efficiently in machine instructions. \\ \\`T` must be a pointer, a `bool`, a float, an integer or an enum. \\ @@ -419,9 +469,20 @@ pub const builtins = [_]Builtin{ .signature = "@cmpxchgWeak(comptime T: type, ptr: *T, expected_value: T, new_value: T, success_order: AtomicOrder, fail_order: AtomicOrder) ?T", .snippet = "@cmpxchgWeak(${1:comptime T: type}, ${2:ptr: *T}, ${3:expected_value: T}, ${4:new_value: T}, ${5:success_order: AtomicOrder}, ${6:fail_order: AtomicOrder})", .documentation = - \\This function performs a weak atomic compare exchange operation. It's the equivalent of this code, except atomic:

{#syntax_block|zig|cmpxchgWeakButNotAtomic#} fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_value: T) ?T { const old_value = ptr.*; if (old_value == expected_value and usuallyTrueButSometimesFalse()) { ptr.* = new_value; return null; } else { return old_value; } } {#end_syntax_block#} + \\This function performs a weak atomic compare exchange operation. It's the equivalent of this code, except atomic: \\ - \\If you are using cmpxchg in a loop, the sporadic failure will be no problem, and `cmpxchgWeak` is the better choice, because it can be implemented more efficiently in machine instructions. However if you need a stronger guarantee, use [@cmpxchgStrong](https://ziglang.org/documentation/master/#cmpxchgStrong). + \\```zig + \\fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_value: T) ?T { + \\ const old_value = ptr.*; + \\ if (old_value == expected_value and usuallyTrueButSometimesFalse()) { + \\ ptr.* = new_value; + \\ return null; + \\ } else { + \\ return old_value; + \\ } + \\} + \\``` + \\If you are using cmpxchg in a loop, the sporadic failure will be no problem, and `cmpxchgWeak` is the better choice, because it can be implemented more efficiently in machine instructions. However if you need a stronger guarantee, use [@cmpxchgStrong](https://ziglang.org/documentation/0.8.0/#cmpxchgStrong). \\ \\`T` must be a pointer, a `bool`, a float, an integer or an enum. \\ @@ -462,24 +523,32 @@ pub const builtins = [_]Builtin{ \\ \\```zig \\const print = @import("std").debug.print; - \\ \\const num1 = blk: { \\ var val1: i32 = 99; \\ @compileLog("comptime val1 = ", val1); \\ val1 = val1 + 1; \\ break :blk val1; \\}; - \\ \\test "main" { \\ @compileLog("comptime in main"); - \\ \\ print("Runtime in main, num1 = {}.\n", .{num1}); \\} \\``` + \\will ouput: \\ - \\will output: + \\If all `@compileLog` calls are removed or not encountered by analysis, the program compiles successfully and the generated executable prints: \\ - \\If all `@compileLog` calls are removed or not encountered by analysis, the program compiles successfully and the generated executable prints:

{#code_begin|test|without_compileLog#} const print = @import("std").debug.print; const num1 = blk: { var val1: i32 = 99; val1 = val1 + 1; break :blk val1; }; test "main" { print("Runtime in main, num1 = {}.\n", .{num1}); }`
+        \\```zig
+        \\const print = @import("std").debug.print;
+        \\const num1 = blk: {
+        \\    var val1: i32 = 99;
+        \\    val1 = val1 + 1;
+        \\    break :blk val1;
+        \\};
+        \\test "main" {
+        \\    print("Runtime in main, num1 = {}.\n", .{num1});
+        \\}
+        \\```
         ,
         .arguments = &.{
             "args: ...",
@@ -487,22 +556,18 @@ pub const builtins = [_]Builtin{
     },
     .{
         .name = "@ctz",
-        .signature = "@ctz(comptime T: type, operand: T)",
-        .snippet = "@ctz(${1:comptime T: type}, ${2:operand: T})",
+        .signature = "@ctz(comptime T: type, integer: T)",
+        .snippet = "@ctz(${1:comptime T: type}, ${2:integer: T})",
         .documentation =
-        \\`T` must be an integer type.
+        \\This function counts the number of least-significant (trailing in a big-Endian sense) zeroes in `integer`.
         \\
-        \\`operand` may be an [integer](https://ziglang.org/documentation/master/#Integers) or [vector](https://ziglang.org/documentation/master/#Vectors).
+        \\If `integer` is known at [comptime](https://ziglang.org/documentation/0.8.0/#comptime), the return type is `comptime_int`. Otherwise, the return type is an unsigned integer with the minimum number of bits that can represent the bit count of the integer type.
         \\
-        \\This function counts the number of least-significant (trailing in a big-Endian sense) zeroes in an integer.
-        \\
-        \\If `operand` is a [comptime](https://ziglang.org/documentation/master/#comptime)-known integer, the return type is `comptime_int`. Otherwise, the return type is an unsigned integer or vector of unsigned integers with the minimum number of bits that can represent the bit count of the integer type.
-        \\
-        \\If `operand` is zero, `@ctz` returns the bit width of integer type `T`.
+        \\If `integer` is zero, `@ctz` returns the bit width of integer type `T`.
         ,
         .arguments = &.{
             "comptime T: type",
-            "operand: T",
+            "integer: T",
         },
     },
     .{
@@ -512,7 +577,8 @@ pub const builtins = [_]Builtin{
         .documentation =
         \\This function can only occur inside `@cImport`.
         \\
-        \\This appends `#undef $name` to the `@cImport` temporary buffer.
+        \\This appends
+        \\`#undef $name`to the `@cImport` temporary buffer.
         ,
         .arguments = &.{
             "comptime name: []u8",
@@ -524,9 +590,9 @@ pub const builtins = [_]Builtin{
         .snippet = "@divExact(${1:numerator: T}, ${2:denominator: T})",
         .documentation =
         \\Exact division. Caller guarantees `denominator != 0` and `@divTrunc(numerator, denominator) * denominator == numerator`.
-        \\  - `@divExact(6, 3) == 2`
-        \\  - `@divExact(a, b) * b == a`
         \\
+        \\ - `@divExact(6, 3) == 2`
+        \\ - `@divExact(a, b) * b == a`
         \\For a function that returns a possible error code, use `@import("std").math.divExact`.
         ,
         .arguments = &.{
@@ -540,9 +606,9 @@ pub const builtins = [_]Builtin{
         .snippet = "@divFloor(${1:numerator: T}, ${2:denominator: T})",
         .documentation =
         \\Floored division. Rounds toward negative infinity. For unsigned integers it is the same as `numerator / denominator`. Caller guarantees `denominator != 0` and `!(@typeInfo(T) == .Int and T.is_signed and numerator == std.math.minInt(T) and denominator == -1)`.
-        \\  - `@divFloor(-5, 3) == -2`
-        \\  - `(@divFloor(a, b) * b) + @mod(a, b) == a`
         \\
+        \\ - `@divFloor(-5, 3) == -2`
+        \\ - `(@divFloor(a, b) * b) + @mod(a, b) == a`
         \\For a function that returns a possible error code, use `@import("std").math.divFloor`.
         ,
         .arguments = &.{
@@ -556,9 +622,9 @@ pub const builtins = [_]Builtin{
         .snippet = "@divTrunc(${1:numerator: T}, ${2:denominator: T})",
         .documentation =
         \\Truncated division. Rounds toward zero. For unsigned integers it is the same as `numerator / denominator`. Caller guarantees `denominator != 0` and `!(@typeInfo(T) == .Int and T.is_signed and numerator == std.math.minInt(T) and denominator == -1)`.
-        \\  - `@divTrunc(-5, 3) == -1`
-        \\  - `(@divTrunc(a, b) * b) + @rem(a, b) == a`
         \\
+        \\ - `@divTrunc(-5, 3) == -1`
+        \\ - `(@divTrunc(a, b) * b) + @rem(a, b) == a`
         \\For a function that returns a possible error code, use `@import("std").math.divTrunc`.
         ,
         .arguments = &.{
@@ -568,10 +634,10 @@ pub const builtins = [_]Builtin{
     },
     .{
         .name = "@embedFile",
-        .signature = "@embedFile(comptime path: []const u8) *const [N:0]u8",
+        .signature = "@embedFile(comptime path: []const u8) *const [X:0]u8",
         .snippet = "@embedFile(${1:comptime path: []const u8})",
         .documentation =
-        \\This function returns a compile time constant pointer to null-terminated, fixed-size array with length equal to the byte count of the file given by `path`. The contents of the array are the contents of the file. This is equivalent to a [string literal](https://ziglang.org/documentation/master/#String-Literals-and-Unicode-Code-Point-Literals) with the file contents.
+        \\This function returns a compile time constant pointer to null-terminated, fixed-size array with length equal to the byte count of the file given by `path`. The contents of the array are the contents of the file. This is equivalent to a [string literal](https://ziglang.org/documentation/0.8.0/#String-Literals-and-Unicode-Code-Point-Literals) with the file contents.
         \\
         \\`path` is absolute or relative to the current file, just like `@import`.
         ,
@@ -586,7 +652,7 @@ pub const builtins = [_]Builtin{
         .documentation =
         \\Converts an enumeration value into its integer tag type. When a tagged union is passed, the tag value is used as the enumeration value.
         \\
-        \\If there is only one possible enum value, the result is a `comptime_int` known at [comptime](https://ziglang.org/documentation/master/#comptime).
+        \\If there is only one possible enum value, the resut is a `comptime_int` known at [comptime](https://ziglang.org/documentation/0.8.0/#comptime).
         ,
         .arguments = &.{
             "enum_or_tagged_union: anytype",
@@ -594,7 +660,7 @@ pub const builtins = [_]Builtin{
     },
     .{
         .name = "@errorName",
-        .signature = "@errorName(err: anyerror) [:0]const u8",
+        .signature = "@errorName(err: anyerror) []const u8",
         .snippet = "@errorName(${1:err: anyerror})",
         .documentation =
         \\This function returns the string representation of an error. The string representation of `error.OutOfMem` is `"OutOfMem"`.
@@ -610,7 +676,7 @@ pub const builtins = [_]Builtin{
         .signature = "@errorReturnTrace() ?*builtin.StackTrace",
         .snippet = "@errorReturnTrace()",
         .documentation =
-        \\If the binary is built with error return tracing, and this function is invoked in a function that calls a function with an error or error union return type, returns a stack trace object. Otherwise returns [null](https://ziglang.org/documentation/master/#null).
+        \\If the binary is built with error return tracing, and this function is invoked in a function that calls a function with an error or error union return type, returns a stack trace object. Otherwise returns [null](https://ziglang.org/documentation/0.8.0/#null).
         ,
         .arguments = &.{},
     },
@@ -620,10 +686,10 @@ pub const builtins = [_]Builtin{
         .snippet = "@errorToInt(${1:err: anytype})",
         .documentation =
         \\Supports the following types:
-        \\  - [The Global Error Set](https://ziglang.org/documentation/master/#The-Global-Error-Set)
-        \\  - [Error Set Type](https://ziglang.org/documentation/master/#Error-Set-Type)
-        \\  - [Error Union Type](https://ziglang.org/documentation/master/#Error-Union-Type)
         \\
+        \\ - [The Global Error Set](https://ziglang.org/documentation/0.8.0/#The-Global-Error-Set)
+        \\ - [Error Set Type](https://ziglang.org/documentation/0.8.0/#Error-Set-Type)
+        \\ - [Error Union Type](https://ziglang.org/documentation/0.8.0/#Error-Union-Type)
         \\Converts an error to the integer representation of an error.
         \\
         \\It is generally recommended to avoid this cast, as the integer representation of an error is not stable across source code changes.
@@ -637,7 +703,7 @@ pub const builtins = [_]Builtin{
         .signature = "@errSetCast(comptime T: DestType, value: anytype) DestType",
         .snippet = "@errSetCast(${1:comptime T: DestType}, ${2:value: anytype})",
         .documentation =
-        \\Converts an error value from one error set to another error set. Attempting to convert an error which is not in the destination error set results in safety-protected [Undefined Behavior](https://ziglang.org/documentation/master/#Undefined-Behavior).
+        \\Converts an error value from one error set to another error set. Attempting to convert an error which is not in the destination error set results in safety-protected [Undefined Behavior](https://ziglang.org/documentation/0.8.0/#Undefined-Behavior).
         ,
         .arguments = &.{
             "comptime T: DestType",
@@ -646,45 +712,31 @@ pub const builtins = [_]Builtin{
     },
     .{
         .name = "@export",
-        .signature = "@export(declaration, comptime options: std.builtin.ExportOptions) void",
-        .snippet = "@export(${1:declaration}, ${2:comptime options: std.builtin.ExportOptions})",
+        .signature = "@export(identifier, comptime options: std.builtin.ExportOptions) void",
+        .snippet = "@export(${1:identifier}, ${2:comptime options: std.builtin.ExportOptions})",
         .documentation =
         \\Creates a symbol in the output object file.
         \\
-        \\`declaration` must be one of two things:
-        \\  - An identifier (`x`) identifying a [function](https://ziglang.org/documentation/master/#Functions) or a [variable](https://ziglang.org/documentation/master/#Container-Level-Variables).
-        \\  - Field access (`x.y`) looking up a [function](https://ziglang.org/documentation/master/#Functions) or a [variable](https://ziglang.org/documentation/master/#Container-Level-Variables).
-        \\
-        \\This builtin can be called from a [comptime](https://ziglang.org/documentation/master/#comptime) block to conditionally export symbols. When `declaration` is a function with the C calling convention and `options.linkage` is `Strong`, this is equivalent to the `export` keyword used on a function:
+        \\This function can be called from a [comptime](https://ziglang.org/documentation/0.8.0/#comptime) block to conditionally export symbols. When `identifier` is a function with the C calling convention and `options.linkage` is `Strong`, this is equivalent to the `export` keyword used on a function:
         \\
         \\```zig
         \\comptime {
         \\    @export(internalName, .{ .name = "foo", .linkage = .Strong });
         \\}
-        \\
         \\fn internalName() callconv(.C) void {}
         \\```
-        \\
         \\This is equivalent to:
         \\
-        \\```zig
-        \\export fn foo() void {}
-        \\```
-        \\
+        \\`export fn foo() void {}`
         \\Note that even when using `export`, `@"foo"` syntax can be used to choose any string for the symbol name:
         \\
-        \\```zig
-        \\export fn @"A function name that is a complete sentence."() void {}
-        \\```
-        \\
+        \\`export fn @"A function name that is a complete sentence."() void {}`
         \\When looking at the resulting object, you can see the symbol is used verbatim:
         \\
-        \\```zig
-        \\00000000000001f0 T A function name that is a complete sentence.
-        \\```
+        \\`00000000000001f0 T A function name that is a complete sentence.`
         ,
         .arguments = &.{
-            "declaration",
+            "identifier",
             "comptime options: std.builtin.ExportOptions",
         },
     },
@@ -718,7 +770,30 @@ pub const builtins = [_]Builtin{
         .signature = "@field(lhs: anytype, comptime field_name: []const u8) (field)",
         .snippet = "@field(${1:lhs: anytype}, ${2:comptime field_name: []const u8})",
         .documentation =
-        \\Performs field access by a compile-time string. Works on both fields and declarations.

{#code_begin|test|field_decl_access_by_string#} const std = @import("std"); const Point = struct { x: u32, y: u32, pub var z: u32 = 1; }; test "field access by string" { const expect = std.testing.expect; var p = Point{ .x = 0, .y = 0 }; @field(p, "x") = 4; @field(p, "y") = @field(p, "x") + 1; try expect(@field(p, "x") == 4); try expect(@field(p, "y") == 5); } test "decl access by string" { const expect = std.testing.expect; try expect(@field(Point, "z") == 1); @field(Point, "z") = 2; try expect(@field(Point, "z") == 2); }`
+        \\Performs field access by a compile-time string. Works on both fields and declarations.
+        \\
+        \\```zig
+        \\const std = @import("std");
+        \\const Point = struct {
+        \\    x: u32,
+        \\    y: u32,
+        \\    pub var z: u32 = 1;
+        \\};
+        \\test "field access by string" {
+        \\    const expect = std.testing.expect;
+        \\    var p = Point{ .x = 0, .y = 0 };
+        \\    @field(p, "x") = 4;
+        \\    @field(p, "y") = @field(p, "x") + 1;
+        \\    try expect(@field(p, "x") == 4);
+        \\    try expect(@field(p, "y") == 5);
+        \\}
+        \\test "decl access by string" {
+        \\    const expect = std.testing.expect;
+        \\    try expect(@field(Point, "z") == 1);
+        \\    @field(Point, "z") = 2;
+        \\    try expect(@field(Point, "z") == 2);
+        \\}
+        \\```
         ,
         .arguments = &.{
             "lhs: anytype",
@@ -727,7 +802,7 @@ pub const builtins = [_]Builtin{
     },
     .{
         .name = "@fieldParentPtr",
-        .signature = "@fieldParentPtr(comptime ParentType: type, comptime field_name: []const u8, field_ptr: *T) *ParentType",
+        .signature = "@fieldParentPtr(comptime ParentType: type, comptime field_name: []const u8,    field_ptr: *T) *ParentType",
         .snippet = "@fieldParentPtr(${1:comptime ParentType: type}, ${2:comptime field_name: []const u8}, ${3:field_ptr: *T})",
         .documentation =
         \\Given a pointer to a field, returns the base pointer of a struct.
@@ -757,7 +832,7 @@ pub const builtins = [_]Builtin{
         .documentation =
         \\Converts the integer part of a floating point number to the destination type.
         \\
-        \\If the integer part of the floating point number cannot fit in the destination type, it invokes safety-checked [Undefined Behavior](https://ziglang.org/documentation/master/#Undefined-Behavior).
+        \\If the integer part of the floating point number cannot fit in the destination type, it invokes safety-checked [Undefined Behavior](https://ziglang.org/documentation/0.8.0/#Undefined-Behavior).
         ,
         .arguments = &.{
             "comptime DestType: type",
@@ -769,9 +844,9 @@ pub const builtins = [_]Builtin{
         .signature = "@frame() *@Frame(func)",
         .snippet = "@frame()",
         .documentation =
-        \\This function returns a pointer to the frame for a given function. This type can be [coerced](https://ziglang.org/documentation/master/#Type-Coercion) to `anyframe->T` and to `anyframe`, where `T` is the return type of the function in scope.
+        \\This function returns a pointer to the frame for a given function. This type can be [coerced](https://ziglang.org/documentation/0.8.0/#Type-Coercion) to `anyframe->T` and to `anyframe`, where `T` is the return type of the function in scope.
         \\
-        \\This function does not mark a suspension point, but it does cause the function in scope to become an [async function](https://ziglang.org/documentation/master/#Async-Functions).
+        \\This function does not mark a suspension point, but it does cause the function in scope to become an [async function](https://ziglang.org/documentation/0.8.0/#Async-Functions).
         ,
         .arguments = &.{},
     },
@@ -780,9 +855,20 @@ pub const builtins = [_]Builtin{
         .signature = "@Frame(func: anytype) type",
         .snippet = "@Frame(${1:func: anytype})",
         .documentation =
-        \\This function returns the frame type of a function. This works for [Async Functions](https://ziglang.org/documentation/master/#Async-Functions) as well as any function without a specific calling convention.
+        \\This function returns the frame type of a function. This works for [Async Functions](https://ziglang.org/documentation/0.8.0/#Async-Functions) as well as any function without a specific calling convention.
         \\
-        \\This type is suitable to be used as the return type of [async](https://ziglang.org/documentation/master/#Async-and-Await) which allows one to, for example, heap-allocate an async function frame:

{#code_begin|test|heap_allocated_frame#} const std = @import("std"); test "heap allocated frame" { const frame = try std.heap.page_allocator.create(@Frame(func)); frame.* = async func(); } fn func() void { suspend {} }`
+        \\This type is suitable to be used as the return type of [async](https://ziglang.org/documentation/0.8.0/#Async-and-Await) which allows one to, for example, heap-allocate an async function frame:
+        \\
+        \\```zig
+        \\const std = @import("std");
+        \\test "heap allocated frame" {
+        \\    const frame = try std.heap.page_allocator.create(@Frame(func));
+        \\    frame.* = async func();
+        \\}
+        \\fn func() void {
+        \\    suspend {}
+        \\}
+        \\```
         ,
         .arguments = &.{
             "func: anytype",
@@ -808,7 +894,7 @@ pub const builtins = [_]Builtin{
         .documentation =
         \\This is the same as `@sizeOf(@Frame(func))`, where `func` may be runtime-known.
         \\
-        \\This function is typically used in conjunction with [@asyncCall](https://ziglang.org/documentation/master/#asyncCall).
+        \\This function is typically used in conjunction with [@asyncCall](https://ziglang.org/documentation/0.8.0/#asyncCall).
         ,
         .arguments = &.{},
     },
@@ -817,8 +903,27 @@ pub const builtins = [_]Builtin{
         .signature = "@hasDecl(comptime Container: type, comptime name: []const u8) bool",
         .snippet = "@hasDecl(${1:comptime Container: type}, ${2:comptime name: []const u8})",
         .documentation =
-        \\Returns whether or not a [struct](https://ziglang.org/documentation/master/#struct), [enum](https://ziglang.org/documentation/master/#enum), or [union](https://ziglang.org/documentation/master/#union) has a declaration matching `name`.

{#code_begin|test|hasDecl#} const std = @import("std"); const expect = std.testing.expect; const Foo = struct { nope: i32, pub var blah = "xxx"; const hi = 1; }; test "@hasDecl" { try expect(@hasDecl(Foo, "blah")); // Even though `hi` is private, @hasDecl returns true because this test is // in the same file scope as Foo. It would return false if Foo was declared // in a different file. try expect(@hasDecl(Foo, "hi")); // @hasDecl is for declarations; not fields. try expect(!@hasDecl(Foo, "nope")); try expect(!@hasDecl(Foo, "nope1234")); }`
-        \\      
+        \\Returns whether or not a [struct](https://ziglang.org/documentation/0.8.0/#struct), [enum](https://ziglang.org/documentation/0.8.0/#enum), or [union](https://ziglang.org/documentation/0.8.0/#union) has a declaration matching `name`.
+        \\
+        \\```zig
+        \\const std = @import("std");
+        \\const expect = std.testing.expect;
+        \\const Foo = struct {
+        \\    nope: i32,
+        \\    pub var blah = "xxx";
+        \\    const hi = 1;
+        \\};
+        \\test "@hasDecl" {
+        \\    try expect(@hasDecl(Foo, "blah"));
+        \\    // Even though `hi` is private, @hasDecl returns true because this test is
+        \\    // in the same file scope as Foo. It would return false if Foo was declared
+        \\    // in a different file.
+        \\    try expect(@hasDecl(Foo, "hi"));
+        \\    // @hasDecl is for declarations; not fields.
+        \\    try expect(!@hasDecl(Foo, "nope"));
+        \\    try expect(!@hasDecl(Foo, "nope1234"));
+        \\}
+        \\```
         ,
         .arguments = &.{
             "comptime Container: type",
@@ -855,8 +960,10 @@ pub const builtins = [_]Builtin{
         \\`path` can be a relative path or it can be the name of a package. If it is a relative path, it is relative to the file that contains the `@import` function call.
         \\
         \\The following packages are always available:
-        \\  - `@import("std")` - Zig Standard Library
-        \\  - `@import("builtin")` - Target-specific information The command `zig build-exe --show-builtin` outputs the source to stdout for reference.
+        \\
+        \\ - `@import("std")` - Zig Standard Library
+        \\ - `@import("builtin")` - Target-specific information The command
+        \\`zig build-exe --show-builtin`outputs the source to stdout for reference.
         ,
         .arguments = &.{
             "comptime path: []u8",
@@ -867,9 +974,9 @@ pub const builtins = [_]Builtin{
         .signature = "@intCast(comptime DestType: type, int: anytype) DestType",
         .snippet = "@intCast(${1:comptime DestType: type}, ${2:int: anytype})",
         .documentation =
-        \\Converts an integer to another integer while keeping the same numerical value. Attempting to convert a number which is out of range of the destination type results in safety-protected [Undefined Behavior](https://ziglang.org/documentation/master/#Undefined-Behavior).
+        \\Converts an integer to another integer while keeping the same numerical value. Attempting to convert a number which is out of range of the destination type results in safety-protected [Undefined Behavior](https://ziglang.org/documentation/0.8.0/#Undefined-Behavior).
         \\
-        \\If `T` is `comptime_int`, then this is semantically equivalent to [Type Coercion](https://ziglang.org/documentation/master/#Type-Coercion).
+        \\If `T` is `comptime_int`, then this is semantically equivalent to [Type Coercion](https://ziglang.org/documentation/0.8.0/#Type-Coercion).
         ,
         .arguments = &.{
             "comptime DestType: type",
@@ -878,31 +985,31 @@ pub const builtins = [_]Builtin{
     },
     .{
         .name = "@intToEnum",
-        .signature = "@intToEnum(comptime DestType: type, integer: anytype) DestType",
-        .snippet = "@intToEnum(${1:comptime DestType: type}, ${2:integer: anytype})",
+        .signature = "@intToEnum(comptime DestType: type, int_value: std.meta.Tag(DestType)) DestType",
+        .snippet = "@intToEnum(${1:comptime DestType: type}, ${2:int_value: std.meta.Tag(DestType)})",
         .documentation =
-        \\Converts an integer into an [enum](https://ziglang.org/documentation/master/#enum) value.
+        \\Converts an integer into an [enum](https://ziglang.org/documentation/0.8.0/#enum) value.
         \\
-        \\Attempting to convert an integer which represents no value in the chosen enum type invokes safety-checked [Undefined Behavior](https://ziglang.org/documentation/master/#Undefined-Behavior).
+        \\Attempting to convert an integer which represents no value in the chosen enum type invokes safety-checked [Undefined Behavior](https://ziglang.org/documentation/0.8.0/#Undefined-Behavior).
         ,
         .arguments = &.{
             "comptime DestType: type",
-            "integer: anytype",
+            "int_value: std.meta.Tag(DestType)",
         },
     },
     .{
         .name = "@intToError",
         .signature = "@intToError(value: std.meta.Int(.unsigned, @sizeOf(anyerror) * 8)) anyerror",
-        .snippet = "@intToError(${1:value: std.meta.Int(.unsigned, @sizeOf(anyerror) * 8)})",
+        .snippet = "@intToError(${1:value: std.meta.Int(.unsigned, @sizeOf(anyerror) * 8})",
         .documentation =
-        \\Converts from the integer representation of an error into [The Global Error Set](https://ziglang.org/documentation/master/#The-Global-Error-Set) type.
+        \\Converts from the integer representation of an error into [The Global Error Set](https://ziglang.org/documentation/0.8.0/#The-Global-Error-Set) type.
         \\
         \\It is generally recommended to avoid this cast, as the integer representation of an error is not stable across source code changes.
         \\
-        \\Attempting to convert an integer that does not correspond to any error results in safety-protected [Undefined Behavior](https://ziglang.org/documentation/master/#Undefined-Behavior).
+        \\Attempting to convert an integer that does not correspond to any error results in safety-protected [Undefined Behavior](https://ziglang.org/documentation/0.8.0/#Undefined-Behavior).
         ,
         .arguments = &.{
-            "value: std.meta.Int(.unsigned, @sizeOf(anyerror) * 8)",
+            "value: std.meta.Int(.unsigned, @sizeOf(anyerror) * 8",
         },
     },
     .{
@@ -910,7 +1017,7 @@ pub const builtins = [_]Builtin{
         .signature = "@intToFloat(comptime DestType: type, int: anytype) DestType",
         .snippet = "@intToFloat(${1:comptime DestType: type}, ${2:int: anytype})",
         .documentation =
-        \\Converts an integer to the closest floating point representation. To convert the other way, use [@floatToInt](https://ziglang.org/documentation/master/#floatToInt). This cast is always safe.
+        \\Converts an integer to the closest floating point representation. To convert the other way, use [@floatToInt](https://ziglang.org/documentation/0.8.0/#floatToInt). This cast is always safe.
         ,
         .arguments = &.{
             "comptime DestType: type",
@@ -922,29 +1029,15 @@ pub const builtins = [_]Builtin{
         .signature = "@intToPtr(comptime DestType: type, address: usize) DestType",
         .snippet = "@intToPtr(${1:comptime DestType: type}, ${2:address: usize})",
         .documentation =
-        \\Converts an integer to a [pointer](https://ziglang.org/documentation/master/#Pointers). To convert the other way, use [@ptrToInt](https://ziglang.org/documentation/master/#ptrToInt).
+        \\Converts an integer to a [pointer](https://ziglang.org/documentation/0.8.0/#Pointers). To convert the other way, use [@ptrToInt](https://ziglang.org/documentation/0.8.0/#ptrToInt).
         \\
-        \\If the destination pointer type does not allow address zero and `address` is zero, this invokes safety-checked [Undefined Behavior](https://ziglang.org/documentation/master/#Undefined-Behavior).
+        \\If the destination pointer type does not allow address zero and `address` is zero, this invokes safety-checked [Undefined Behavior](https://ziglang.org/documentation/0.8.0/#Undefined-Behavior).
         ,
         .arguments = &.{
             "comptime DestType: type",
             "address: usize",
         },
     },
-    .{
-        .name = "@maximum",
-        .signature = "@maximum(a: T, b: T) T",
-        .snippet = "@maximum(${1:a: T}, ${2:b: T})",
-        .documentation =
-        \\Returns the maximum value of `a` and `b`. This builtin accepts integers, floats, and vectors of either. In the latter case, the operation is performed element wise.
-        \\
-        \\NaNs are handled as follows: if one of the operands of a (pairwise) operation is NaN, the other operand is returned. If both operands are NaN, NaN is returned.
-        ,
-        .arguments = &.{
-            "a: T",
-            "b: T",
-        },
-    },
     .{
         .name = "@memcpy",
         .signature = "@memcpy(noalias dest: [*]u8, noalias source: [*]const u8, byte_count: usize)",
@@ -954,10 +1047,7 @@ pub const builtins = [_]Builtin{
         \\
         \\This function is a low level intrinsic with no safety mechanisms. Most code should not use this function, instead using something like this:
         \\
-        \\```zig
-        \\for (source[0..byte_count]) |b, i| dest[i] = b;
-        \\```
-        \\
+        \\`for (source[0..byte_count]) |b, i| dest[i] = b;`
         \\The optimizer is intelligent enough to turn the above snippet into a memcpy.
         \\
         \\There is also a standard library function for this:
@@ -982,10 +1072,7 @@ pub const builtins = [_]Builtin{
         \\
         \\This function is a low level intrinsic with no safety mechanisms. Most code should not use this function, instead using something like this:
         \\
-        \\```zig
-        \\for (dest[0..byte_count]) |*b| b.* = c;
-        \\```
-        \\
+        \\`for (dest[0..byte_count]) |*b| b.* = c;`
         \\The optimizer is intelligent enough to turn the above snippet into a memset.
         \\
         \\There is also a standard library function for this:
@@ -1001,20 +1088,6 @@ pub const builtins = [_]Builtin{
             "byte_count: usize",
         },
     },
-    .{
-        .name = "@minimum",
-        .signature = "@minimum(a: T, b: T) T",
-        .snippet = "@minimum(${1:a: T}, ${2:b: T})",
-        .documentation =
-        \\Returns the minimum value of `a` and `b`. This builtin accepts integers, floats, and vectors of either. In the latter case, the operation is performed element wise.
-        \\
-        \\NaNs are handled as follows: if one of the operands of a (pairwise) operation is NaN, the other operand is returned. If both operands are NaN, NaN is returned.
-        ,
-        .arguments = &.{
-            "a: T",
-            "b: T",
-        },
-    },
     .{
         .name = "@wasmMemorySize",
         .signature = "@wasmMemorySize(index: u32) u32",
@@ -1035,8 +1108,19 @@ pub const builtins = [_]Builtin{
         .documentation =
         \\This function increases the size of the Wasm memory identified by `index` by `delta` in units of unsigned number of Wasm pages. Note that each Wasm page is 64KB in size. On success, returns previous memory size; on failure, if the allocation fails, returns -1.
         \\
-        \\This function is a low level intrinsic with no safety mechanisms usually useful for allocator designers targeting Wasm. So unless you are writing a new allocator from scratch, you should use something like `@import("std").heap.WasmPageAllocator`.

{#code_begin|test|wasmMemoryGrow#} const std = @import("std"); const native_arch = @import("builtin").target.cpu.arch; const expect = std.testing.expect; test "@wasmMemoryGrow" { if (native_arch != .wasm32) return error.SkipZigTest; var prev = @wasmMemorySize(0); try expect(prev == @wasmMemoryGrow(0, 1)); try expect(prev + 1 == @wasmMemorySize(0)); }`
-        \\      
+        \\This function is a low level intrinsic with no safety mechanisms usually useful for allocator designers targeting Wasm. So unless you are writing a new allocator from scratch, you should use something like `@import("std").heap.WasmPageAllocator`.
+        \\
+        \\```zig
+        \\const std = @import("std");
+        \\const native_arch = @import("builtin").target.cpu.arch;
+        \\const expect = std.testing.expect;
+        \\test "@wasmMemoryGrow" {
+        \\    if (native_arch != .wasm32) return error.SkipZigTest;
+        \\    var prev = @wasmMemorySize(0);
+        \\    try expect(prev == @wasmMemoryGrow(0, 1));
+        \\    try expect(prev + 1 == @wasmMemorySize(0));
+        \\}
+        \\```
         ,
         .arguments = &.{
             "index: u32",
@@ -1049,9 +1133,9 @@ pub const builtins = [_]Builtin{
         .snippet = "@mod(${1:numerator: T}, ${2:denominator: T})",
         .documentation =
         \\Modulus division. For unsigned integers this is the same as `numerator % denominator`. Caller guarantees `denominator > 0`.
-        \\  - `@mod(-5, 3) == 1`
-        \\  - `(@divFloor(a, b) * b) + @mod(a, b) == a`
         \\
+        \\ - `@mod(-5, 3) == 1`
+        \\ - `(@divFloor(a, b) * b) + @mod(a, b) == a`
         \\For a function that returns an error code, see `@import("std").math.mod`.
         ,
         .arguments = &.{
@@ -1081,8 +1165,9 @@ pub const builtins = [_]Builtin{
         \\Invokes the panic handler function. By default the panic handler function calls the public `panic` function exposed in the root source file, or if there is not one specified, the `std.builtin.default_panic` function from `std/builtin.zig`.
         \\
         \\Generally it is better to use `@import("std").debug.panic`. However, `@panic` can be useful for 2 scenarios:
-        \\  - From library code, calling the programmer's panic function if they exposed one in the root source file.
-        \\  - When mixing C and Zig code, calling the canonical panic implementation across multiple .o files.
+        \\
+        \\ - From library code, calling the programmer's panic function if they exposed one in the root source file.
+        \\ - When mixing C and Zig code, calling the canonical panic implementation across multiple .o files.
         ,
         .arguments = &.{
             "message: []const u8",
@@ -1090,20 +1175,16 @@ pub const builtins = [_]Builtin{
     },
     .{
         .name = "@popCount",
-        .signature = "@popCount(comptime T: type, operand: T)",
-        .snippet = "@popCount(${1:comptime T: type}, ${2:operand: T})",
+        .signature = "@popCount(comptime T: type, integer: T)",
+        .snippet = "@popCount(${1:comptime T: type}, ${2:integer: T})",
         .documentation =
-        \\`T` must be an integer type.
-        \\
-        \\`operand` may be an [integer](https://ziglang.org/documentation/master/#Integers) or [vector](https://ziglang.org/documentation/master/#Vectors).
-        \\
         \\Counts the number of bits set in an integer.
         \\
-        \\If `operand` is a [comptime](https://ziglang.org/documentation/master/#comptime)-known integer, the return type is `comptime_int`. Otherwise, the return type is an unsigned integer or vector of unsigned integers with the minimum number of bits that can represent the bit count of the integer type.
+        \\If `integer` is known at [comptime](https://ziglang.org/documentation/0.8.0/#comptime), the return type is `comptime_int`. Otherwise, the return type is an unsigned integer with the minimum number of bits that can represent the bit count of the integer type.
         ,
         .arguments = &.{
             "comptime T: type",
-            "operand: T",
+            "integer: T",
         },
     },
     .{
@@ -1113,7 +1194,7 @@ pub const builtins = [_]Builtin{
         .documentation =
         \\Converts a pointer of one type to a pointer of another type.
         \\
-        \\[Optional Pointers](https://ziglang.org/documentation/master/#Optional-Pointers) are allowed. Casting an optional pointer which is [null](https://ziglang.org/documentation/master/#null) to a non-optional pointer invokes safety-checked [Undefined Behavior](https://ziglang.org/documentation/master/#Undefined-Behavior).
+        \\[Optional Pointers](https://ziglang.org/documentation/0.8.0/#Optional-Pointers) are allowed. Casting an optional pointer which is [null](https://ziglang.org/documentation/0.8.0/#null) to a non-optional pointer invokes safety-checked [Undefined Behavior](https://ziglang.org/documentation/0.8.0/#Undefined-Behavior).
         ,
         .arguments = &.{
             "comptime DestType: type",
@@ -1126,12 +1207,12 @@ pub const builtins = [_]Builtin{
         .snippet = "@ptrToInt(${1:value: anytype})",
         .documentation =
         \\Converts `value` to a `usize` which is the address of the pointer. `value` can be one of these types:
-        \\  - `*T`
-        \\  - `?*T`
-        \\  - `fn()`
-        \\  - `?fn()`
         \\
-        \\To convert the other way, use [@intToPtr](https://ziglang.org/documentation/master/#intToPtr)
+        \\ - `*T`
+        \\ - `?*T`
+        \\ - `fn()`
+        \\ - `?fn()`
+        \\To convert the other way, use [@intToPtr](https://ziglang.org/documentation/0.8.0/#intToPtr)
         ,
         .arguments = &.{
             "value: anytype",
@@ -1143,9 +1224,9 @@ pub const builtins = [_]Builtin{
         .snippet = "@rem(${1:numerator: T}, ${2:denominator: T})",
         .documentation =
         \\Remainder division. For unsigned integers this is the same as `numerator % denominator`. Caller guarantees `denominator > 0`.
-        \\  - `@rem(-5, 3) == -2`
-        \\  - `(@divTrunc(a, b) * b) + @rem(a, b) == a`
         \\
+        \\ - `@rem(-5, 3) == -2`
+        \\ - `(@divTrunc(a, b) * b) + @rem(a, b) == a`
         \\For a function that returns an error code, see `@import("std").math.rem`.
         ,
         .arguments = &.{
@@ -1166,20 +1247,6 @@ pub const builtins = [_]Builtin{
         ,
         .arguments = &.{},
     },
-    .{
-        .name = "@select",
-        .signature = "@select(comptime T: type, pred: std.meta.Vector(len, bool), a: std.meta.Vector(len, T), b: std.meta.Vector(len, T)) std.meta.Vector(len, T)",
-        .snippet = "@select(${1:comptime T: type}, ${2:pred: std.meta.Vector(len, bool)}, ${3:a: std.meta.Vector(len, T)}, ${4:b: std.meta.Vector(len, T)})",
-        .documentation =
-        \\Selects values element-wise from `a` or `b` based on `pred`. If `pred[i]` is `true`, the corresponding element in the result will be `a[i]` and otherwise `b[i]`.
-        ,
-        .arguments = &.{
-            "comptime T: type",
-            "pred: std.meta.Vector(len, bool)",
-            "a: std.meta.Vector(len, T)",
-            "b: std.meta.Vector(len, T)",
-        },
-    },
     .{
         .name = "@setAlignStack",
         .signature = "@setAlignStack(comptime alignment: u29)",
@@ -1213,18 +1280,16 @@ pub const builtins = [_]Builtin{
         \\
         \\Example:
         \\
-        \\```zig
-        \\test "foo" {
-        \\    comptime {
-        \\        var i = 0;
-        \\        while (i < 1001) : (i += 1) {}
+        \\1001) : (i += 1) {}
         \\    }
         \\}
         \\```
+        \\Now we use `@setEvalBranchQuota`:
         \\
-        \\Now we use `@setEvalBranchQuota`:

{#code_begin|test|setEvalBranchQuota#} test "foo" { comptime { @setEvalBranchQuota(1001); var i = 0; while (i < 1001) : (i += 1) {} } }`
-        \\
-        \\      
+        \\1001) : (i += 1) {}
+        \\    }
+        \\}
+        \\```
         ,
         .arguments = &.{
             "new_quota: u32",
@@ -1243,16 +1308,16 @@ pub const builtins = [_]Builtin{
         \\    Optimized,
         \\};
         \\```
-        \\
-        \\  - `Strict` (default) - Floating point operations follow strict IEEE compliance.
-        \\  - `Optimized` - Floating point operations may do all of the following: 
    - \\ - Assume the arguments and result are not NaN. Optimizations are required to retain defined behavior over NaNs, but the value of the result is undefined. - \\ - Assume the arguments and result are not +/-Inf. Optimizations are required to retain defined behavior over +/-Inf, but the value of the result is undefined. - \\ - Treat the sign of a zero argument or result as insignificant. - \\ - Use the reciprocal of an argument rather than perform division. - \\ - Perform floating-point contraction (e.g. fusing a multiply followed by an addition into a fused multiply-and-add). - \\ - Perform algebraically equivalent transformations that may change results in floating point (e.g. reassociate). This is equivalent to `-ffast-math` in GCC.
- \\ + \\ - `Strict` (default) - Floating point operations follow strict IEEE compliance. + \\ - `Optimized` - Floating point operations may do all of the following: + \\ - Assume the arguments and result are not NaN. Optimizations are required to retain defined behavior over NaNs, but the value of the result is undefined. + \\ - Assume the arguments and result are not +/-Inf. Optimizations are required to retain defined behavior over +/-Inf, but the value of the result is undefined. + \\ - Treat the sign of a zero argument or result as insignificant. + \\ - Use the reciprocal of an argument rather than perform division. + \\ - Perform floating-point contraction (e.g. fusing a multiply followed by an addition into a fused multiply-and-add). + \\ - Perform algebraically equivalent transformations that may change results in floating point (e.g. reassociate). + \\This is equivalent to + \\`-ffast-math`in GCC. \\The floating point mode is inherited by child scopes, and can be overridden in any scope. You can set the floating point mode in a struct or module scope by using a comptime block. , .arguments = &.{ @@ -1261,7 +1326,7 @@ pub const builtins = [_]Builtin{ }, .{ .name = "@setRuntimeSafety", - .signature = "@setRuntimeSafety(safety_on: bool) void", + .signature = "@setRuntimeSafety(safety_on: bool)", .snippet = "@setRuntimeSafety(${1:safety_on: bool})", .documentation = \\Sets whether runtime safety checks are enabled for the scope that contains the function call. @@ -1278,7 +1343,6 @@ pub const builtins = [_]Builtin{ \\ @setRuntimeSafety(true); \\ var x: u8 = 255; \\ x += 1; - \\ \\ { \\ // The value can be overridden at any scope. So here integer overflow \\ // would not be caught in any build mode. @@ -1289,8 +1353,9 @@ pub const builtins = [_]Builtin{ \\ } \\} \\``` - \\ - \\Note: it is [planned](https://github.com/ziglang/zig/issues/978) to replace `@setRuntimeSafety` with `@optimizeFor` + \\Note: it is + \\[planned](https://github.com/ziglang/zig/issues/978)to replace `@setRuntimeSafety` with + \\`@optimizeFor` , .arguments = &.{ "safety_on: bool", @@ -1301,7 +1366,7 @@ pub const builtins = [_]Builtin{ .signature = "@shlExact(value: T, shift_amt: Log2T) T", .snippet = "@shlExact(${1:value: T}, ${2:shift_amt: Log2T})", .documentation = - \\Performs the left shift operation (`<<`). For unsigned integers, the result is [undefined](https://ziglang.org/documentation/master/#undefined) if any 1 bits are shifted out. For signed integers, the result is [undefined](https://ziglang.org/documentation/master/#undefined) if any bits that disagree with the resultant sign bit are shifted out. + \\`). Caller guarantees that the shift will not shift any 1 bits out. \\ \\The type of `shift_amt` is an unsigned integer with `log2(T.bit_count)` bits. This is because `shift_amt >= T.bit_count` is undefined behavior. , @@ -1315,7 +1380,7 @@ pub const builtins = [_]Builtin{ .signature = "@shlWithOverflow(comptime T: type, a: T, shift_amt: Log2T, result: *T) bool", .snippet = "@shlWithOverflow(${1:comptime T: type}, ${2:a: T}, ${3:shift_amt: Log2T}, ${4:result: *T})", .documentation = - \\Performs `result.* = a << b`. If overflow or underflow occurs, stores the overflowed bits in `result` and returns `true`. If no overflow or underflow occurs, returns `false`. + \\b`. If overflow or underflow occurs, stores the overflowed bits in `result` and returns `true`. If no overflow or underflow occurs, returns `false`. \\ \\The type of `shift_amt` is an unsigned integer with `log2(T.bit_count)` bits. This is because `shift_amt >= T.bit_count` is undefined behavior. , @@ -1345,7 +1410,7 @@ pub const builtins = [_]Builtin{ .signature = "@shuffle(comptime E: type, a: std.meta.Vector(a_len, E), b: std.meta.Vector(b_len, E), comptime mask: std.meta.Vector(mask_len, i32)) std.meta.Vector(mask_len, E)", .snippet = "@shuffle(${1:comptime E: type}, ${2:a: std.meta.Vector(a_len, E)}, ${3:b: std.meta.Vector(b_len, E)}, ${4:comptime mask: std.meta.Vector(mask_len, i32)})", .documentation = - \\Constructs a new [vector](https://ziglang.org/documentation/master/#Vectors) by selecting elements from `a` and `b` based on `mask`. + \\Constructs a new [vector](https://ziglang.org/documentation/0.8.0/#Vectors) by selecting elements from `a` and `b` based on `mask`. \\ \\Each element in `mask` selects an element from either `a` or `b`. Positive numbers select from `a` starting at 0. Negative values select from `b`, starting at `-1` and going down. It is recommended to use the `~` operator from indexes from `b` so that both indexes can start from `0` (i.e. `~@as(i32, 0)` is `-1`). \\ @@ -1355,7 +1420,7 @@ pub const builtins = [_]Builtin{ \\ \\If `a` or `b` is `undefined`, it is equivalent to a vector of all `undefined` with the same length as the other vector. If both vectors are `undefined`, `@shuffle` returns a vector with all elements `undefined`. \\ - \\`E` must be an [integer](https://ziglang.org/documentation/master/#Integers), [float](https://ziglang.org/documentation/master/#Floats), [pointer](https://ziglang.org/documentation/master/#Pointers), or `bool`. The mask may be any vector length, and its length determines the result length. + \\`E` must be an [integer](https://ziglang.org/documentation/0.8.0/#Integers), [float](https://ziglang.org/documentation/0.8.0/#Floats), [pointer](https://ziglang.org/documentation/0.8.0/#Pointers), or `bool`. The mask may be any vector length, and its length determines the result length. , .arguments = &.{ "comptime E: type", @@ -1371,7 +1436,7 @@ pub const builtins = [_]Builtin{ .documentation = \\This function returns the number of bytes it takes to store `T` in memory. The result is a target-specific compile time constant. \\ - \\This size may contain padding bytes. If there were two consecutive T in memory, this would be the offset in bytes between element at index 0 and the element at index 1. For [integer](https://ziglang.org/documentation/master/#Integers), consider whether you want to use `@sizeOf(T)` or `@typeInfo(T).Int.bits`. + \\This size may contain padding bytes. If there were two consecutive T in memory, this would be the offset in bytes between element at index 0 and the element at index 1. For [integer](https://ziglang.org/documentation/0.8.0/#Integers), consider whether you want to use `@sizeOf(T)` or `@typeInfo(T).Int.bits`. \\ \\This function measures the size at runtime. For types that are disallowed at runtime, such as `comptime_int` and `type`, the result is `0`. , @@ -1384,14 +1449,19 @@ pub const builtins = [_]Builtin{ .signature = "@splat(comptime len: u32, scalar: anytype) std.meta.Vector(len, @TypeOf(scalar))", .snippet = "@splat(${1:comptime len: u32}, ${2:scalar: anytype})", .documentation = - \\Produces a vector of length `len` where each element is the value `scalar`:

{#code_begin|test|vector_splat#} const std = @import("std"); const expect = std.testing.expect; test "vector @splat" { const scalar: u32 = 5; const result = @splat(4, scalar); comptime try expect(@TypeOf(result) == std.meta.Vector(4, u32)); try expect(std.mem.eql(u32, &@as([4]u32, result), &[_]u32{ 5, 5, 5, 5 })); }`
-        \\      
+        \\Produces a vector of length `len` where each element is the value `scalar`:
         \\
-        \\
-        \\      `scalar` must be an [integer](https://ziglang.org/documentation/master/#Integers), [bool](https://ziglang.org/documentation/master/#Primitive-Types),
-        \\      [float](https://ziglang.org/documentation/master/#Floats), or [pointer](https://ziglang.org/documentation/master/#Pointers).
-        \\      

- \\ + \\```zig + \\const std = @import("std"); + \\const expect = std.testing.expect; + \\test "vector @splat" { + \\ const scalar: u32 = 5; + \\ const result = @splat(4, scalar); + \\ comptime try expect(@TypeOf(result) == std.meta.Vector(4, u32)); + \\ try expect(std.mem.eql(u32, &@as([4]u32, result), &[_]u32{ 5, 5, 5, 5 })); + \\} + \\``` + \\`scalar` must be an [integer](https://ziglang.org/documentation/0.8.0/#Integers), [bool](https://ziglang.org/documentation/0.8.0/#Primitive-Types), [float](https://ziglang.org/documentation/0.8.0/#Floats), or [pointer](https://ziglang.org/documentation/0.8.0/#Pointers). , .arguments = &.{ "comptime len: u32", @@ -1403,15 +1473,28 @@ pub const builtins = [_]Builtin{ .signature = "@reduce(comptime op: std.builtin.ReduceOp, value: anytype) std.meta.Child(value)", .snippet = "@reduce(${1:comptime op: std.builtin.ReduceOp}, ${2:value: anytype})", .documentation = - \\Transforms a [vector](https://ziglang.org/documentation/master/#Vectors) into a scalar value by performing a sequential horizontal reduction of its elements using the specified operator `op`. + \\Transforms a [vector](https://ziglang.org/documentation/0.8.0/#Vectors) into a scalar value by performing a sequential horizontal reduction of its elements using the specified operator `op`. \\ \\Not every operator is available for every vector element type: - \\ - `.And`, `.Or`, `.Xor` are available for `bool` vectors, - \\ - `.Min`, `.Max`, `.Add`, `.Mul` are available for [floating point](https://ziglang.org/documentation/master/#Floats) vectors, - \\ - Every operator is available for [integer](https://ziglang.org/documentation/master/#Integers) vectors. \\ - \\Note that `.Add` and `.Mul` reductions on integral types are wrapping; when applied on floating point types the operation associativity is preserved, unless the float mode is set to `Optimized`.

{#code_begin|test|vector_reduce#} const std = @import("std"); const expect = std.testing.expect; test "vector @reduce" { const value: std.meta.Vector(4, i32) = [_]i32{ 1, -1, 1, -1 }; const result = value > @splat(4, @as(i32, 0)); // result is { true, false, true, false }; comptime try expect(@TypeOf(result) == std.meta.Vector(4, bool)); const is_all_true = @reduce(.And, result); comptime try expect(@TypeOf(is_all_true) == bool); try expect(is_all_true == false); }`
-        \\      
+        \\ - `.And`, `.Or`, `.Xor` are available for `bool` vectors,
+        \\ - `.Min`, `.Max`, `.Add`, `.Mul` are available for [floating point](https://ziglang.org/documentation/0.8.0/#Floats) vectors,
+        \\ - Every operator is available for [integer](https://ziglang.org/documentation/0.8.0/#Integers) vectors.
+        \\Note that `.Add` and `.Mul` reductions on integral types are wrapping; when applied on floating point types the operation associativity is preserved, unless the float mode is set to `Optimized`.
+        \\
+        \\```zig
+        \\const std = @import("std");
+        \\const expect = std.testing.expect;
+        \\test "vector @reduce" {
+        \\    const value: std.meta.Vector(4, i32) = [_]i32{ 1, -1, 1, -1 };
+        \\    const result = value > @splat(4, @as(i32, 0));
+        \\    // result is { true, false, true, false };
+        \\    comptime try expect(@TypeOf(result) == std.meta.Vector(4, bool));
+        \\    const is_all_true = @reduce(.And, result);
+        \\    comptime try expect(@TypeOf(is_all_true) == bool);
+        \\    try expect(is_all_true == false);
+        \\}
+        \\```
         ,
         .arguments = &.{
             "comptime op: std.builtin.ReduceOp",
@@ -1423,7 +1506,22 @@ pub const builtins = [_]Builtin{
         .signature = "@src() std.builtin.SourceLocation",
         .snippet = "@src()",
         .documentation =
-        \\Returns a `SourceLocation` struct representing the function's name and location in the source code. This must be called in a function.

{#code_begin|test|source_location#} const std = @import("std"); const expect = std.testing.expect; test "@src" { try doTheTest(); } fn doTheTest() !void { const src = @src(); try expect(src.line == 9); try expect(src.column == 17); try expect(std.mem.endsWith(u8, src.fn_name, "doTheTest")); try expect(std.mem.endsWith(u8, src.file, "source_location.zig")); }`
+        \\Returns a `SourceLocation` struct representing the function's name and location in the source code. This must be called in a function.
+        \\
+        \\```zig
+        \\const std = @import("std");
+        \\const expect = std.testing.expect;
+        \\test "@src" {
+        \\    try doTheTest();
+        \\}
+        \\fn doTheTest() !void {
+        \\    const src = @src();
+        \\    try expect(src.line == 9);
+        \\    try expect(src.column == 17);
+        \\    try expect(std.mem.endsWith(u8, src.fn_name, "doTheTest"));
+        \\    try expect(std.mem.endsWith(u8, src.file, "test.zig"));
+        \\}
+        \\```
         ,
         .arguments = &.{},
     },
@@ -1434,7 +1532,8 @@ pub const builtins = [_]Builtin{
         .documentation =
         \\Performs the square root of a floating point number. Uses a dedicated hardware instruction when available.
         \\
-        \\Supports [Floats](https://ziglang.org/documentation/master/#Floats) and [Vectors](https://ziglang.org/documentation/master/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
+        \\Supports [Floats](https://ziglang.org/documentation/0.8.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.8.0/#Vectors) of floats, with the caveat that
+        \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
         ,
         .arguments = &.{
             "value: anytype",
@@ -1445,9 +1544,10 @@ pub const builtins = [_]Builtin{
         .signature = "@sin(value: anytype) @TypeOf(value)",
         .snippet = "@sin(${1:value: anytype})",
         .documentation =
-        \\Sine trigonometric function on a floating point number. Uses a dedicated hardware instruction when available.
+        \\Sine trigometric function on a floating point number. Uses a dedicated hardware instruction when available.
         \\
-        \\Supports [Floats](https://ziglang.org/documentation/master/#Floats) and [Vectors](https://ziglang.org/documentation/master/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
+        \\Supports [Floats](https://ziglang.org/documentation/0.8.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.8.0/#Vectors) of floats, with the caveat that
+        \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
         ,
         .arguments = &.{
             "value: anytype",
@@ -1458,9 +1558,10 @@ pub const builtins = [_]Builtin{
         .signature = "@cos(value: anytype) @TypeOf(value)",
         .snippet = "@cos(${1:value: anytype})",
         .documentation =
-        \\Cosine trigonometric function on a floating point number. Uses a dedicated hardware instruction when available.
+        \\Cosine trigometric function on a floating point number. Uses a dedicated hardware instruction when available.
         \\
-        \\Supports [Floats](https://ziglang.org/documentation/master/#Floats) and [Vectors](https://ziglang.org/documentation/master/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
+        \\Supports [Floats](https://ziglang.org/documentation/0.8.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.8.0/#Vectors) of floats, with the caveat that
+        \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
         ,
         .arguments = &.{
             "value: anytype",
@@ -1473,7 +1574,8 @@ pub const builtins = [_]Builtin{
         .documentation =
         \\Base-e exponential function on a floating point number. Uses a dedicated hardware instruction when available.
         \\
-        \\Supports [Floats](https://ziglang.org/documentation/master/#Floats) and [Vectors](https://ziglang.org/documentation/master/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
+        \\Supports [Floats](https://ziglang.org/documentation/0.8.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.8.0/#Vectors) of floats, with the caveat that
+        \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
         ,
         .arguments = &.{
             "value: anytype",
@@ -1486,7 +1588,8 @@ pub const builtins = [_]Builtin{
         .documentation =
         \\Base-2 exponential function on a floating point number. Uses a dedicated hardware instruction when available.
         \\
-        \\Supports [Floats](https://ziglang.org/documentation/master/#Floats) and [Vectors](https://ziglang.org/documentation/master/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
+        \\Supports [Floats](https://ziglang.org/documentation/0.8.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.8.0/#Vectors) of floats, with the caveat that
+        \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
         ,
         .arguments = &.{
             "value: anytype",
@@ -1499,7 +1602,8 @@ pub const builtins = [_]Builtin{
         .documentation =
         \\Returns the natural logarithm of a floating point number. Uses a dedicated hardware instruction when available.
         \\
-        \\Supports [Floats](https://ziglang.org/documentation/master/#Floats) and [Vectors](https://ziglang.org/documentation/master/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
+        \\Supports [Floats](https://ziglang.org/documentation/0.8.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.8.0/#Vectors) of floats, with the caveat that
+        \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
         ,
         .arguments = &.{
             "value: anytype",
@@ -1512,7 +1616,8 @@ pub const builtins = [_]Builtin{
         .documentation =
         \\Returns the logarithm to the base 2 of a floating point number. Uses a dedicated hardware instruction when available.
         \\
-        \\Supports [Floats](https://ziglang.org/documentation/master/#Floats) and [Vectors](https://ziglang.org/documentation/master/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
+        \\Supports [Floats](https://ziglang.org/documentation/0.8.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.8.0/#Vectors) of floats, with the caveat that
+        \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
         ,
         .arguments = &.{
             "value: anytype",
@@ -1525,7 +1630,8 @@ pub const builtins = [_]Builtin{
         .documentation =
         \\Returns the logarithm to the base 10 of a floating point number. Uses a dedicated hardware instruction when available.
         \\
-        \\Supports [Floats](https://ziglang.org/documentation/master/#Floats) and [Vectors](https://ziglang.org/documentation/master/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
+        \\Supports [Floats](https://ziglang.org/documentation/0.8.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.8.0/#Vectors) of floats, with the caveat that
+        \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
         ,
         .arguments = &.{
             "value: anytype",
@@ -1538,7 +1644,8 @@ pub const builtins = [_]Builtin{
         .documentation =
         \\Returns the absolute value of a floating point number. Uses a dedicated hardware instruction when available.
         \\
-        \\Supports [Floats](https://ziglang.org/documentation/master/#Floats) and [Vectors](https://ziglang.org/documentation/master/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
+        \\Supports [Floats](https://ziglang.org/documentation/0.8.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.8.0/#Vectors) of floats, with the caveat that
+        \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
         ,
         .arguments = &.{
             "value: anytype",
@@ -1551,7 +1658,8 @@ pub const builtins = [_]Builtin{
         .documentation =
         \\Returns the largest integral value not greater than the given floating point number. Uses a dedicated hardware instruction when available.
         \\
-        \\Supports [Floats](https://ziglang.org/documentation/master/#Floats) and [Vectors](https://ziglang.org/documentation/master/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
+        \\Supports [Floats](https://ziglang.org/documentation/0.8.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.8.0/#Vectors) of floats, with the caveat that
+        \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
         ,
         .arguments = &.{
             "value: anytype",
@@ -1564,7 +1672,8 @@ pub const builtins = [_]Builtin{
         .documentation =
         \\Returns the largest integral value not less than the given floating point number. Uses a dedicated hardware instruction when available.
         \\
-        \\Supports [Floats](https://ziglang.org/documentation/master/#Floats) and [Vectors](https://ziglang.org/documentation/master/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
+        \\Supports [Floats](https://ziglang.org/documentation/0.8.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.8.0/#Vectors) of floats, with the caveat that
+        \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
         ,
         .arguments = &.{
             "value: anytype",
@@ -1577,7 +1686,8 @@ pub const builtins = [_]Builtin{
         .documentation =
         \\Rounds the given floating point number to an integer, towards zero. Uses a dedicated hardware instruction when available.
         \\
-        \\Supports [Floats](https://ziglang.org/documentation/master/#Floats) and [Vectors](https://ziglang.org/documentation/master/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
+        \\Supports [Floats](https://ziglang.org/documentation/0.8.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.8.0/#Vectors) of floats, with the caveat that
+        \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
         ,
         .arguments = &.{
             "value: anytype",
@@ -1590,7 +1700,8 @@ pub const builtins = [_]Builtin{
         .documentation =
         \\Rounds the given floating point number to an integer, away from zero. Uses a dedicated hardware instruction when available.
         \\
-        \\Supports [Floats](https://ziglang.org/documentation/master/#Floats) and [Vectors](https://ziglang.org/documentation/master/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
+        \\Supports [Floats](https://ziglang.org/documentation/0.8.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.8.0/#Vectors) of floats, with the caveat that
+        \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
         ,
         .arguments = &.{
             "value: anytype",
@@ -1612,12 +1723,12 @@ pub const builtins = [_]Builtin{
     },
     .{
         .name = "@tagName",
-        .signature = "@tagName(value: anytype) [:0]const u8",
+        .signature = "@tagName(value: anytype) []const u8",
         .snippet = "@tagName(${1:value: anytype})",
         .documentation =
-        \\Converts an enum value or union value to a string literal representing the name.
+        \\Converts an enum value or union value to a slice of bytes representing the name.
         \\
-        \\If the enum is non-exhaustive and the tag value does not map to a name, it invokes safety-checked [Undefined Behavior](https://ziglang.org/documentation/master/#Undefined-Behavior).
+        \\If the enum is non-exhaustive and the tag value does not map to a name, it invokes safety-checked [Undefined Behavior](https://ziglang.org/documentation/0.8.0/#Undefined-Behavior).
         ,
         .arguments = &.{
             "value: anytype",
@@ -1628,13 +1739,27 @@ pub const builtins = [_]Builtin{
         .signature = "@This() type",
         .snippet = "@This()",
         .documentation =
-        \\Returns the innermost struct, enum, or union that this function call is inside. This can be useful for an anonymous struct that needs to refer to itself:

{#code_begin|test|this_innermost#} const std = @import("std"); const expect = std.testing.expect; test "@This()" { var items = [_]i32{ 1, 2, 3, 4 }; const list = List(i32){ .items = items[0..] }; try expect(list.length() == 4); } fn List(comptime T: type) type { return struct { const Self = @This(); items: []T, fn length(self: Self) usize { return self.items.len; } }; }`
-        \\      
+        \\Returns the innermost struct, enum, or union that this function call is inside. This can be useful for an anonymous struct that needs to refer to itself:
         \\
-        \\
-        \\      When `@This()` is used at file scope, it returns a reference to the
-        \\      struct that corresponds to the current file.
-        \\      
+        \\```zig
+        \\const std = @import("std");
+        \\const expect = std.testing.expect;
+        \\test "@This()" {
+        \\    var items = [_]i32{ 1, 2, 3, 4 };
+        \\    const list = List(i32){ .items = items[0..] };
+        \\    try expect(list.length() == 4);
+        \\}
+        \\fn List(comptime T: type) type {
+        \\    return struct {
+        \\        const Self = @This();
+        \\        items: []T,
+        \\        fn length(self: Self) usize {
+        \\            return self.items.len;
+        \\        }
+        \\    };
+        \\}
+        \\```
+        \\When `@This()` is used at global scope, it returns a reference to the struct that corresponds to the current file.
         ,
         .arguments = &.{},
     },
@@ -1645,29 +1770,25 @@ pub const builtins = [_]Builtin{
         .documentation =
         \\This function truncates bits from an integer type, resulting in a smaller or same-sized integer type.
         \\
-        \\The following produces safety-checked [Undefined Behavior](https://ziglang.org/documentation/master/#Undefined-Behavior):
+        \\The following produces safety-checked [Undefined Behavior](https://ziglang.org/documentation/0.8.0/#Undefined-Behavior):
         \\
         \\```zig
         \\test "integer cast panic" {
         \\    var a: u16 = 0xabcd;
         \\    var b: u8 = @intCast(u8, a);
-        \\    _ = b;
         \\}
         \\```
-        \\
         \\However this is well defined and working code:
         \\
         \\```zig
         \\const std = @import("std");
         \\const expect = std.testing.expect;
-        \\
         \\test "integer truncation" {
         \\    var a: u16 = 0xabcd;
         \\    var b: u8 = @truncate(u8, a);
         \\    try expect(b == 0xcd);
         \\}
         \\```
-        \\
         \\This function always truncates the significant bits of the integer, regardless of endianness on the target platform.
         ,
         .arguments = &.{
@@ -1680,36 +1801,37 @@ pub const builtins = [_]Builtin{
         .signature = "@Type(comptime info: std.builtin.TypeInfo) type",
         .snippet = "@Type(${1:comptime info: std.builtin.TypeInfo})",
         .documentation =
-        \\This function is the inverse of [@typeInfo](https://ziglang.org/documentation/master/#typeInfo). It reifies type information into a `type`.
+        \\This function is the inverse of [@typeInfo](https://ziglang.org/documentation/0.8.0/#typeInfo). It reifies type information into a `type`.
         \\
         \\It is available for the following types:
-        \\  - `type`
-        \\  - `noreturn`
-        \\  - `void`
-        \\  - `bool`
-        \\  - [Integers](https://ziglang.org/documentation/master/#Integers) - The maximum bit count for an integer type is `65535`.
-        \\  - [Floats](https://ziglang.org/documentation/master/#Floats)
-        \\  - [Pointers](https://ziglang.org/documentation/master/#Pointers)
-        \\  - `comptime_int`
-        \\  - `comptime_float`
-        \\  - `@TypeOf(undefined)`
-        \\  - `@TypeOf(null)`
-        \\  - [Arrays](https://ziglang.org/documentation/master/#Arrays)
-        \\  - [Optionals](https://ziglang.org/documentation/master/#Optionals)
-        \\  - [Error Set Type](https://ziglang.org/documentation/master/#Error-Set-Type)
-        \\  - [Error Union Type](https://ziglang.org/documentation/master/#Error-Union-Type)
-        \\  - [Vectors](https://ziglang.org/documentation/master/#Vectors)
-        \\  - [opaque](https://ziglang.org/documentation/master/#opaque)
-        \\  - [@Frame](https://ziglang.org/documentation/master/#Frame)
-        \\  - `anyframe`
-        \\  - [struct](https://ziglang.org/documentation/master/#struct)
-        \\  - [enum](https://ziglang.org/documentation/master/#enum)
-        \\  - [Enum Literals](https://ziglang.org/documentation/master/#Enum-Literals)
-        \\  - [union](https://ziglang.org/documentation/master/#union)
         \\
+        \\ - `type`
+        \\ - `noreturn`
+        \\ - `void`
+        \\ - `bool`
+        \\ - [Integers](https://ziglang.org/documentation/0.8.0/#Integers) - The maximum bit count for an integer type is `65535`.
+        \\ - [Floats](https://ziglang.org/documentation/0.8.0/#Floats)
+        \\ - [Pointers](https://ziglang.org/documentation/0.8.0/#Pointers)
+        \\ - `comptime_int`
+        \\ - `comptime_float`
+        \\ - `@TypeOf(undefined)`
+        \\ - `@TypeOf(null)`
+        \\ - [Arrays](https://ziglang.org/documentation/0.8.0/#Arrays)
+        \\ - [Optionals](https://ziglang.org/documentation/0.8.0/#Optionals)
+        \\ - [Error Set Type](https://ziglang.org/documentation/0.8.0/#Error-Set-Type)
+        \\ - [Error Union Type](https://ziglang.org/documentation/0.8.0/#Error-Union-Type)
+        \\ - [Vectors](https://ziglang.org/documentation/0.8.0/#Vectors)
+        \\ - [opaque](https://ziglang.org/documentation/0.8.0/#opaque)
+        \\ - [@Frame](https://ziglang.org/documentation/0.8.0/#Frame)
+        \\ - `anyframe`
+        \\ - [struct](https://ziglang.org/documentation/0.8.0/#struct)
+        \\ - [enum](https://ziglang.org/documentation/0.8.0/#enum)
+        \\ - [Enum Literals](https://ziglang.org/documentation/0.8.0/#Enum-Literals)
+        \\ - [union](https://ziglang.org/documentation/0.8.0/#union)
         \\For these types, `@Type` is not available:
-        \\  - [Functions](https://ziglang.org/documentation/master/#Functions)
-        \\  - BoundFn
+        \\
+        \\ - [Functions](https://ziglang.org/documentation/0.8.0/#Functions)
+        \\ - BoundFn
         ,
         .arguments = &.{
             "comptime info: std.builtin.TypeInfo",
@@ -1722,7 +1844,7 @@ pub const builtins = [_]Builtin{
         .documentation =
         \\Provides type reflection.
         \\
-        \\For [structs](https://ziglang.org/documentation/master/#struct), [unions](https://ziglang.org/documentation/master/#union), [enums](https://ziglang.org/documentation/master/#enum), and [error sets](https://ziglang.org/documentation/master/#Error-Set-Type), the fields are guaranteed to be in the same order as declared. For declarations, the order is unspecified.
+        \\For [structs](https://ziglang.org/documentation/0.8.0/#struct), [unions](https://ziglang.org/documentation/0.8.0/#union), [enums](https://ziglang.org/documentation/0.8.0/#enum), and [error sets](https://ziglang.org/documentation/0.8.0/#Error-Set-Type), the fields are guaranteed to be in the same order as declared. For declarations, the order is unspecified.
         ,
         .arguments = &.{
             "comptime T: type",
@@ -1730,7 +1852,7 @@ pub const builtins = [_]Builtin{
     },
     .{
         .name = "@typeName",
-        .signature = "@typeName(T: type) *const [N:0]u8",
+        .signature = "@typeName(T: type) [N]u8",
         .snippet = "@typeName(${1:T: type})",
         .documentation =
         \\This function returns the string representation of a type, as an array. It is equivalent to a string literal of the type name.
@@ -1744,9 +1866,25 @@ pub const builtins = [_]Builtin{
         .signature = "@TypeOf(...) type",
         .snippet = "@TypeOf(${1:...})",
         .documentation =
-        \\`@TypeOf` is a special builtin function that takes any (nonzero) number of expressions as parameters and returns the type of the result, using [Peer Type Resolution](https://ziglang.org/documentation/master/#Peer-Type-Resolution).
+        \\`@TypeOf` is a special builtin function that takes any (nonzero) number of expressions as parameters and returns the type of the result, using [Peer Type Resolution](https://ziglang.org/documentation/0.8.0/#Peer-Type-Resolution).
         \\
-        \\The expressions are evaluated, however they are guaranteed to have no *runtime* side-effects:

{#code_begin|test|no_runtime_side_effects#} const std = @import("std"); const expect = std.testing.expect; test "no runtime side effects" { var data: i32 = 0; const T = @TypeOf(foo(i32, &data)); comptime try expect(T == i32); try expect(data == 0); } fn foo(comptime T: type, ptr: *T) T { ptr.* += 1; return ptr.*; }`
+        \\The expressions are evaluated, however they are guaranteed to have no
+        \\**runtime** side-effects:
+        \\
+        \\```zig
+        \\const std = @import("std");
+        \\const expect = std.testing.expect;
+        \\test "no runtime side effects" {
+        \\    var data: i32 = 0;
+        \\    const T = @TypeOf(foo(i32, &data));
+        \\    comptime try expect(T == i32);
+        \\    try expect(data == 0);
+        \\}
+        \\fn foo(comptime T: type, ptr: *T) T {
+        \\    ptr.* += 1;
+        \\    return ptr.*;
+        \\}
+        \\```
         ,
         .arguments = &.{
             "...",
@@ -1757,9 +1895,9 @@ pub const builtins = [_]Builtin{
         .signature = "@unionInit(comptime Union: type, comptime active_field_name: []const u8, init_expr) Union",
         .snippet = "@unionInit(${1:comptime Union: type}, ${2:comptime active_field_name: []const u8}, ${3:init_expr})",
         .documentation =
-        \\This is the same thing as [union](https://ziglang.org/documentation/master/#union) initialization syntax, except that the field name is a [comptime](https://ziglang.org/documentation/master/#comptime)-known value rather than an identifier token.
+        \\This is the same thing as [union](https://ziglang.org/documentation/0.8.0/#union) initialization syntax, except that the field name is a [comptime](https://ziglang.org/documentation/0.8.0/#comptime)-known value rather than an identifier token.
         \\
-        \\`@unionInit` forwards its [result location](https://ziglang.org/documentation/master/#Result-Location-Semantics) to `init_expr`.
+        \\`@unionInit` forwards its [result location](https://ziglang.org/documentation/0.8.0/#Result-Location-Semantics) to `init_expr`.
         ,
         .arguments = &.{
             "comptime Union: type",
@@ -1768,3 +1906,5 @@ pub const builtins = [_]Builtin{
         },
     },
 };
+
+// DO NOT EDIT
diff --git a/src/data/0.8.1.zig b/src/data/0.8.1.zig
index 6c1a8a7..5f03917 100644
--- a/src/data/0.8.1.zig
+++ b/src/data/0.8.1.zig
@@ -1,3 +1,8 @@
+//! DO NOT EDIT
+//! If you want to update this file run:
+//! `zig build gen -- --generate-version-data 0.8.1` (requires an internet connection)
+//! GENERATED BY src/config_gen/config_gen.zig
+
 const Builtin = struct {
     name: []const u8,
     signature: []const u8,
@@ -28,7 +33,7 @@ pub const builtins = [_]Builtin{
         .documentation =
         \\`ptr` can be `*T`, `fn()`, `?*T`, `?fn()`, or `[]T`. It returns the same type as `ptr` except with the alignment adjusted to the new value.
         \\
-        \\A [pointer alignment safety check](https://ziglang.org/documentation/master/#Incorrect-Pointer-Alignment) is added to the generated code to make sure the pointer is aligned as promised.
+        \\A [pointer alignment safety check](https://ziglang.org/documentation/0.8.1/#Incorrect-Pointer-Alignment) is added to the generated code to make sure the pointer is aligned as promised.
         ,
         .arguments = &.{
             "comptime alignment: u29",
@@ -48,8 +53,7 @@ pub const builtins = [_]Builtin{
         \\    assert(*u32 == *align(@alignOf(u32)) u32);
         \\}
         \\```
-        \\
-        \\The result is a target-specific compile time constant. It is guaranteed to be less than or equal to [@sizeOf(T)](https://ziglang.org/documentation/master/#@sizeOf).
+        \\The result is a target-specific compile time constant. It is guaranteed to be less than or equal to [@sizeOf(T)](https://ziglang.org/documentation/0.8.1/#sizeOf).
         ,
         .arguments = &.{
             "comptime T: type",
@@ -60,7 +64,7 @@ pub const builtins = [_]Builtin{
         .signature = "@as(comptime T: type, expression) T",
         .snippet = "@as(${1:comptime T: type}, ${2:expression})",
         .documentation =
-        \\Performs [Type Coercion](https://ziglang.org/documentation/master/#Type-Coercion). This cast is allowed when the conversion is unambiguous and safe, and is the preferred way to convert between types, whenever possible.
+        \\Performs [Type Coercion](https://ziglang.org/documentation/0.8.1/#Type-Coercion). This cast is allowed when the conversion is unambiguous and safe, and is the preferred way to convert between types, whenever possible.
         ,
         .arguments = &.{
             "comptime T: type",
@@ -70,19 +74,38 @@ pub const builtins = [_]Builtin{
     .{
         .name = "@asyncCall",
         .signature = "@asyncCall(frame_buffer: []align(@alignOf(@Frame(anyAsyncFunction))) u8, result_ptr, function_ptr, args: anytype) anyframe->T",
-        .snippet = "@asyncCall(${1:frame_buffer: []align(@alignOf(@Frame(anyAsyncFunction))) u8}, ${2:result_ptr}, ${3:function_ptr}, ${4:args: anytype})",
+        .snippet = "@asyncCall(${1:frame_buffer: []align(@alignOf(@Frame(anyAsyncFunction)})",
         .documentation =
-        \\`@asyncCall` performs an `async` call on a function pointer, which may or may not be an [async function](https://ziglang.org/documentation/master/#Async-Functions).
+        \\`@asyncCall` performs an `async` call on a function pointer, which may or may not be an [async function](https://ziglang.org/documentation/0.8.1/#Async-Functions).
         \\
-        \\The provided `frame_buffer` must be large enough to fit the entire function frame. This size can be determined with [@frameSize](https://ziglang.org/documentation/master/#frameSize). To provide a too-small buffer invokes safety-checked [Undefined Behavior](https://ziglang.org/documentation/master/#Undefined-Behavior).
+        \\The provided `frame_buffer` must be large enough to fit the entire function frame. This size can be determined with [@frameSize](https://ziglang.org/documentation/0.8.1/#frameSize). To provide a too-small buffer invokes safety-checked [Undefined Behavior](https://ziglang.org/documentation/0.8.1/#Undefined-Behavior).
         \\
-        \\`result_ptr` is optional ([null](https://ziglang.org/documentation/master/#null) may be provided). If provided, the function call will write its result directly to the result pointer, which will be available to read after [await](https://ziglang.org/documentation/master/#Async-and-Await) completes. Any result location provided to `await` will copy the result from `result_ptr`.

{#code_begin|test|async_struct_field_fn_pointer#} const std = @import("std"); const expect = std.testing.expect; test "async fn pointer in a struct field" { var data: i32 = 1; const Foo = struct { bar: fn (*i32) callconv(.Async) void, }; var foo = Foo{ .bar = func }; var bytes: [64]u8 align(@alignOf(@Frame(func))) = undefined; const f = @asyncCall(&bytes, {}, foo.bar, .{&data}); try expect(data == 2); resume f; try expect(data == 4); } fn func(y: *i32) void { defer y.* += 2; y.* += 1; suspend {} }`
+        \\`result_ptr` is optional ([null](https://ziglang.org/documentation/0.8.1/#null) may be provided). If provided, the function call will write its result directly to the result pointer, which will be available to read after [await](https://ziglang.org/documentation/0.8.1/#Async-and-Await) completes. Any result location provided to `await` will copy the result from `result_ptr`.
+        \\
+        \\```zig
+        \\const std = @import("std");
+        \\const expect = std.testing.expect;
+        \\test "async fn pointer in a struct field" {
+        \\    var data: i32 = 1;
+        \\    const Foo = struct {
+        \\        bar: fn (*i32) callconv(.Async) void,
+        \\    };
+        \\    var foo = Foo{ .bar = func };
+        \\    var bytes: [64]u8 align(@alignOf(@Frame(func))) = undefined;
+        \\    const f = @asyncCall(&bytes, {}, foo.bar, .{&data});
+        \\    try expect(data == 2);
+        \\    resume f;
+        \\    try expect(data == 4);
+        \\}
+        \\fn func(y: *i32) void {
+        \\    defer y.* += 2;
+        \\    y.* += 1;
+        \\    suspend {}
+        \\}
+        \\```
         ,
         .arguments = &.{
-            "frame_buffer: []align(@alignOf(@Frame(anyAsyncFunction))) u8",
-            "result_ptr",
-            "function_ptr",
-            "args: anytype",
+            "frame_buffer: []align(@alignOf(@Frame(anyAsyncFunction)",
         },
     },
     .{
@@ -110,15 +133,16 @@ pub const builtins = [_]Builtin{
         \\`T` must be a pointer, a `bool`, a float, an integer or an enum.
         \\
         \\Supported operations:
-        \\  - `.Xchg` - stores the operand unmodified. Supports enums, integers and floats.
-        \\  - `.Add` - for integers, twos complement wraparound addition. Also supports [Floats](https://ziglang.org/documentation/master/#Floats).
-        \\  - `.Sub` - for integers, twos complement wraparound subtraction. Also supports [Floats](https://ziglang.org/documentation/master/#Floats).
-        \\  - `.And` - bitwise and
-        \\  - `.Nand` - bitwise nand
-        \\  - `.Or` - bitwise or
-        \\  - `.Xor` - bitwise xor
-        \\  - `.Max` - stores the operand if it is larger. Supports integers and floats.
-        \\  - `.Min` - stores the operand if it is smaller. Supports integers and floats.
+        \\
+        \\ - `.Xchg` - stores the operand unmodified. Supports enums, integers and floats.
+        \\ - `.Add` - for integers, twos complement wraparound addition. Also supports [Floats](https://ziglang.org/documentation/0.8.1/#Floats).
+        \\ - `.Sub` - for integers, twos complement wraparound subtraction. Also supports [Floats](https://ziglang.org/documentation/0.8.1/#Floats).
+        \\ - `.And` - bitwise and
+        \\ - `.Nand` - bitwise nand
+        \\ - `.Or` - bitwise or
+        \\ - `.Xor` - bitwise xor
+        \\ - `.Max` - stores the operand if it is larger. Supports integers and floats.
+        \\ - `.Min` - stores the operand if it is smaller. Supports integers and floats.
         ,
         .arguments = &.{
             "comptime T: type",
@@ -156,9 +180,9 @@ pub const builtins = [_]Builtin{
         \\Asserts that `@typeInfo(DestType) != .Pointer`. Use `@ptrCast` or `@intToPtr` if you need this.
         \\
         \\Can be used for these things for example:
-        \\  - Convert `f32` to `u32` bits
-        \\  - Convert `i32` to `u32` preserving twos complement
         \\
+        \\ - Convert `f32` to `u32` bits
+        \\ - Convert `i32` to `u32` preserving twos complement
         \\Works at compile-time if `value` is known at compile time. It's a compile error to bitcast a struct to a scalar type of the same size since structs have undefined layout. However if the struct is packed then it works.
         ,
         .arguments = &.{
@@ -173,7 +197,7 @@ pub const builtins = [_]Builtin{
         .documentation =
         \\Returns the bit offset of a field relative to its containing struct.
         \\
-        \\For non [packed structs](https://ziglang.org/documentation/master/#packed-struct), this will always be divisible by `8`. For packed structs, non-byte-aligned fields will share a byte offset, but they will have different bit offsets.
+        \\For non [packed structs](https://ziglang.org/documentation/0.8.1/#packed-struct), this will always be divisible by `8`. For packed structs, non-byte-aligned fields will share a byte offset, but they will have different bit offsets.
         ,
         .arguments = &.{
             "comptime T: type",
@@ -185,7 +209,7 @@ pub const builtins = [_]Builtin{
         .signature = "@boolToInt(value: bool) u1",
         .snippet = "@boolToInt(${1:value: bool})",
         .documentation =
-        \\Converts `true` to `@as(u1, 1)` and `false` to `@as(u1, 0)`.
+        \\Converts `true` to `u1(1)` and `false` to `u1(0)`.
         \\
         \\If the value is known at compile-time, the return type is `comptime_int` instead of `u1`.
         ,
@@ -240,11 +264,11 @@ pub const builtins = [_]Builtin{
         .documentation =
         \\`T` must be an integer type with bit count evenly divisible by 8.
         \\
-        \\`operand` may be an [integer](https://ziglang.org/documentation/master/#Integers) or [vector](https://ziglang.org/documentation/master/#Vectors).
+        \\`operand` may be an [integer](https://ziglang.org/documentation/0.8.1/#Integers) or [vector](https://ziglang.org/documentation/0.8.1/#Vectors).
         \\
         \\Swaps the byte order of the integer. This converts a big endian integer to a little endian integer, and converts a little endian integer to a big endian integer.
         \\
-        \\Note that for the purposes of memory layout with respect to endianness, the integer type should be related to the number of bytes reported by [@sizeOf](https://ziglang.org/documentation/master/#sizeOf) bytes. This is demonstrated with `u24`. `@sizeOf(u24) == 4`, which means that a `u24` stored in memory takes 4 bytes, and those 4 bytes are what are swapped on a little vs big endian system. On the other hand, if `T` is specified to be `u24`, then only 3 bytes are reversed.
+        \\Note that for the purposes of memory layout with respect to endianness, the integer type should be related to the number of bytes reported by [@sizeOf](https://ziglang.org/documentation/0.8.1/#sizeOf) bytes. This is demonstrated with `u24`. `@sizeOf(u24) == 4`, which means that a `u24` stored in memory takes 4 bytes, and those 4 bytes are what are swapped on a little vs big endian system. On the other hand, if `T` is specified to be `u24`, then only 3 bytes are reversed.
         ,
         .arguments = &.{
             "comptime T: type",
@@ -268,9 +292,9 @@ pub const builtins = [_]Builtin{
         },
     },
     .{
-        .name = "@offsetOf",
-        .signature = "@offsetOf(comptime T: type, comptime field_name: []const u8) comptime_int",
-        .snippet = "@offsetOf(${1:comptime T: type}, ${2:comptime field_name: []const u8})",
+        .name = "@byteOffsetOf",
+        .signature = "@byteOffsetOf(comptime T: type, comptime field_name: []const u8) comptime_int",
+        .snippet = "@byteOffsetOf(${1:comptime T: type}, ${2:comptime field_name: []const u8})",
         .documentation =
         \\Returns the byte offset of a field relative to its containing struct.
         ,
@@ -288,17 +312,47 @@ pub const builtins = [_]Builtin{
         \\
         \\```zig
         \\const expect = @import("std").testing.expect;
-        \\
         \\test "noinline function call" {
         \\    try expect(@call(.{}, add, .{3, 9}) == 12);
         \\}
-        \\
         \\fn add(a: i32, b: i32) i32 {
         \\    return a + b;
         \\}
         \\```
+        \\`@call` allows more flexibility than normal function call syntax does. The `CallOptions` struct is reproduced here:
         \\
-        \\`@call` allows more flexibility than normal function call syntax does. The `CallOptions` struct is reproduced here:

{#syntax_block|zig|builtin.CallOptions struct#} pub const CallOptions = struct { modifier: Modifier = .auto, /// Only valid when `Modifier` is `Modifier.async_kw`. stack: ?[]align(std.Target.stack_align) u8 = null, pub const Modifier = enum { /// Equivalent to function call syntax. auto, /// Equivalent to async keyword used with function call syntax. async_kw, /// Prevents tail call optimization. This guarantees that the return /// address will point to the callsite, as opposed to the callsite's /// callsite. If the call is otherwise required to be tail-called /// or inlined, a compile error is emitted instead. never_tail, /// Guarantees that the call will not be inlined. If the call is /// otherwise required to be inlined, a compile error is emitted instead. never_inline, /// Asserts that the function call will not suspend. This allows a /// non-async function to call an async function. no_async, /// Guarantees that the call will be generated with tail call optimization. /// If this is not possible, a compile error is emitted instead. always_tail, /// Guarantees that the call will inlined at the callsite. /// If this is not possible, a compile error is emitted instead. always_inline, /// Evaluates the call at compile-time. If the call cannot be completed at /// compile-time, a compile error is emitted instead. compile_time, }; }; {#end_syntax_block#} + \\```zig + \\pub const CallOptions = struct { + \\ modifier: Modifier = .auto, + \\ stack: ?[]align(std.Target.stack_align) u8 = null, + \\ pub const Modifier = enum { + \\ /// Equivalent to function call syntax. + \\ auto, + \\ /// Equivalent to async keyword used with function call syntax. + \\ async_kw, + \\ /// Prevents tail call optimization. This guarantees that the return + \\ /// address will point to the callsite, as opposed to the callsite's + \\ /// callsite. If the call is otherwise required to be tail-called + \\ /// or inlined, a compile error is emitted instead. + \\ never_tail, + \\ /// Guarantees that the call will not be inlined. If the call is + \\ /// otherwise required to be inlined, a compile error is emitted instead. + \\ never_inline, + \\ /// Asserts that the function call will not suspend. This allows a + \\ /// non-async function to call an async function. + \\ no_async, + \\ /// Guarantees that the call will be generated with tail call optimization. + \\ /// If this is not possible, a compile error is emitted instead. + \\ always_tail, + \\ /// Guarantees that the call will inlined at the callsite. + \\ /// If this is not possible, a compile error is emitted instead. + \\ always_inline, + \\ /// Evaluates the call at compile-time. If the call cannot be completed at + \\ /// compile-time, a compile error is emitted instead. + \\ compile_time, + \\ }; + \\}; + \\``` , .arguments = &.{ "options: std.builtin.CallOptions", @@ -313,15 +367,14 @@ pub const builtins = [_]Builtin{ .documentation = \\This function can only occur inside `@cImport`. \\ - \\This appends `#define $name $value` to the `@cImport` temporary buffer. + \\This appends + \\`#define $name $value`to the `@cImport` temporary buffer. \\ - \\To define without a value, like this:`#define _GNU_SOURCE` + \\To define without a value, like this: \\ - \\Use the void value, like this: + \\`#define _GNU_SOURCE`Use the void value, like this: \\ - \\```zig - \\@cDefine("_GNU_SOURCE", {}) - \\``` + \\`@cDefine("_GNU_SOURCE", {})` , .arguments = &.{ "comptime name: []u8", @@ -340,8 +393,9 @@ pub const builtins = [_]Builtin{ \\Usually you should only have one `@cImport` in your entire application, because it saves the compiler from invoking clang multiple times, and prevents inline functions from being duplicated. \\ \\Reasons for having multiple `@cImport` expressions would be: - \\ - To avoid a symbol collision, for example if foo.h and bar.h both `#define CONNECTION_COUNT` - \\ - To analyze the C code with different preprocessor defines + \\ + \\ - To avoid a symbol collision, for example if foo.h and bar.h both + \\`#define CONNECTION_COUNT` - To analyze the C code with different preprocessor defines , .arguments = &.{ "expression", @@ -354,7 +408,8 @@ pub const builtins = [_]Builtin{ .documentation = \\This function can only occur inside `@cImport`. \\ - \\This appends `#include <$path>\n` to the `c_import` temporary buffer. + \\This appends + \\`#include <$path>\n`to the `c_import` temporary buffer. , .arguments = &.{ "comptime path: []u8", @@ -362,22 +417,18 @@ pub const builtins = [_]Builtin{ }, .{ .name = "@clz", - .signature = "@clz(comptime T: type, operand: T)", - .snippet = "@clz(${1:comptime T: type}, ${2:operand: T})", + .signature = "@clz(comptime T: type, integer: T)", + .snippet = "@clz(${1:comptime T: type}, ${2:integer: T})", .documentation = - \\`T` must be an integer type. + \\This function counts the number of most-significant (leading in a big-Endian sense) zeroes in `integer`. \\ - \\`operand` may be an [integer](https://ziglang.org/documentation/master/#Integers) or [vector](https://ziglang.org/documentation/master/#Vectors). + \\If `integer` is known at [comptime](https://ziglang.org/documentation/0.8.1/#comptime), the return type is `comptime_int`. Otherwise, the return type is an unsigned integer with the minimum number of bits that can represent the bit count of the integer type. \\ - \\This function counts the number of most-significant (leading in a big-Endian sense) zeroes in an integer. - \\ - \\If `operand` is a [comptime](https://ziglang.org/documentation/master/#comptime)-known integer, the return type is `comptime_int`. Otherwise, the return type is an unsigned integer or vector of unsigned integers with the minimum number of bits that can represent the bit count of the integer type. - \\ - \\If `operand` is zero, `@clz` returns the bit width of integer type `T`. + \\If `integer` is zero, `@clz` returns the bit width of integer type `T`. , .arguments = &.{ "comptime T: type", - "operand: T", + "integer: T", }, }, .{ @@ -398,8 +449,7 @@ pub const builtins = [_]Builtin{ \\ } \\} \\``` - \\ - \\If you are using cmpxchg in a loop, [@cmpxchgWeak](https://ziglang.org/documentation/master/#cmpxchgWeak) is the better choice, because it can be implemented more efficiently in machine instructions. + \\If you are using cmpxchg in a loop, [@cmpxchgWeak](https://ziglang.org/documentation/0.8.1/#cmpxchgWeak) is the better choice, because it can be implemented more efficiently in machine instructions. \\ \\`T` must be a pointer, a `bool`, a float, an integer or an enum. \\ @@ -419,9 +469,20 @@ pub const builtins = [_]Builtin{ .signature = "@cmpxchgWeak(comptime T: type, ptr: *T, expected_value: T, new_value: T, success_order: AtomicOrder, fail_order: AtomicOrder) ?T", .snippet = "@cmpxchgWeak(${1:comptime T: type}, ${2:ptr: *T}, ${3:expected_value: T}, ${4:new_value: T}, ${5:success_order: AtomicOrder}, ${6:fail_order: AtomicOrder})", .documentation = - \\This function performs a weak atomic compare exchange operation. It's the equivalent of this code, except atomic:

{#syntax_block|zig|cmpxchgWeakButNotAtomic#} fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_value: T) ?T { const old_value = ptr.*; if (old_value == expected_value and usuallyTrueButSometimesFalse()) { ptr.* = new_value; return null; } else { return old_value; } } {#end_syntax_block#} + \\This function performs a weak atomic compare exchange operation. It's the equivalent of this code, except atomic: \\ - \\If you are using cmpxchg in a loop, the sporadic failure will be no problem, and `cmpxchgWeak` is the better choice, because it can be implemented more efficiently in machine instructions. However if you need a stronger guarantee, use [@cmpxchgStrong](https://ziglang.org/documentation/master/#cmpxchgStrong). + \\```zig + \\fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_value: T) ?T { + \\ const old_value = ptr.*; + \\ if (old_value == expected_value and usuallyTrueButSometimesFalse()) { + \\ ptr.* = new_value; + \\ return null; + \\ } else { + \\ return old_value; + \\ } + \\} + \\``` + \\If you are using cmpxchg in a loop, the sporadic failure will be no problem, and `cmpxchgWeak` is the better choice, because it can be implemented more efficiently in machine instructions. However if you need a stronger guarantee, use [@cmpxchgStrong](https://ziglang.org/documentation/0.8.1/#cmpxchgStrong). \\ \\`T` must be a pointer, a `bool`, a float, an integer or an enum. \\ @@ -462,24 +523,32 @@ pub const builtins = [_]Builtin{ \\ \\```zig \\const print = @import("std").debug.print; - \\ \\const num1 = blk: { \\ var val1: i32 = 99; \\ @compileLog("comptime val1 = ", val1); \\ val1 = val1 + 1; \\ break :blk val1; \\}; - \\ \\test "main" { \\ @compileLog("comptime in main"); - \\ \\ print("Runtime in main, num1 = {}.\n", .{num1}); \\} \\``` + \\will ouput: \\ - \\will output: + \\If all `@compileLog` calls are removed or not encountered by analysis, the program compiles successfully and the generated executable prints: \\ - \\If all `@compileLog` calls are removed or not encountered by analysis, the program compiles successfully and the generated executable prints:

{#code_begin|test|without_compileLog#} const print = @import("std").debug.print; const num1 = blk: { var val1: i32 = 99; val1 = val1 + 1; break :blk val1; }; test "main" { print("Runtime in main, num1 = {}.\n", .{num1}); }`
+        \\```zig
+        \\const print = @import("std").debug.print;
+        \\const num1 = blk: {
+        \\    var val1: i32 = 99;
+        \\    val1 = val1 + 1;
+        \\    break :blk val1;
+        \\};
+        \\test "main" {
+        \\    print("Runtime in main, num1 = {}.\n", .{num1});
+        \\}
+        \\```
         ,
         .arguments = &.{
             "args: ...",
@@ -487,22 +556,18 @@ pub const builtins = [_]Builtin{
     },
     .{
         .name = "@ctz",
-        .signature = "@ctz(comptime T: type, operand: T)",
-        .snippet = "@ctz(${1:comptime T: type}, ${2:operand: T})",
+        .signature = "@ctz(comptime T: type, integer: T)",
+        .snippet = "@ctz(${1:comptime T: type}, ${2:integer: T})",
         .documentation =
-        \\`T` must be an integer type.
+        \\This function counts the number of least-significant (trailing in a big-Endian sense) zeroes in `integer`.
         \\
-        \\`operand` may be an [integer](https://ziglang.org/documentation/master/#Integers) or [vector](https://ziglang.org/documentation/master/#Vectors).
+        \\If `integer` is known at [comptime](https://ziglang.org/documentation/0.8.1/#comptime), the return type is `comptime_int`. Otherwise, the return type is an unsigned integer with the minimum number of bits that can represent the bit count of the integer type.
         \\
-        \\This function counts the number of least-significant (trailing in a big-Endian sense) zeroes in an integer.
-        \\
-        \\If `operand` is a [comptime](https://ziglang.org/documentation/master/#comptime)-known integer, the return type is `comptime_int`. Otherwise, the return type is an unsigned integer or vector of unsigned integers with the minimum number of bits that can represent the bit count of the integer type.
-        \\
-        \\If `operand` is zero, `@ctz` returns the bit width of integer type `T`.
+        \\If `integer` is zero, `@ctz` returns the bit width of integer type `T`.
         ,
         .arguments = &.{
             "comptime T: type",
-            "operand: T",
+            "integer: T",
         },
     },
     .{
@@ -512,7 +577,8 @@ pub const builtins = [_]Builtin{
         .documentation =
         \\This function can only occur inside `@cImport`.
         \\
-        \\This appends `#undef $name` to the `@cImport` temporary buffer.
+        \\This appends
+        \\`#undef $name`to the `@cImport` temporary buffer.
         ,
         .arguments = &.{
             "comptime name: []u8",
@@ -524,9 +590,9 @@ pub const builtins = [_]Builtin{
         .snippet = "@divExact(${1:numerator: T}, ${2:denominator: T})",
         .documentation =
         \\Exact division. Caller guarantees `denominator != 0` and `@divTrunc(numerator, denominator) * denominator == numerator`.
-        \\  - `@divExact(6, 3) == 2`
-        \\  - `@divExact(a, b) * b == a`
         \\
+        \\ - `@divExact(6, 3) == 2`
+        \\ - `@divExact(a, b) * b == a`
         \\For a function that returns a possible error code, use `@import("std").math.divExact`.
         ,
         .arguments = &.{
@@ -540,9 +606,9 @@ pub const builtins = [_]Builtin{
         .snippet = "@divFloor(${1:numerator: T}, ${2:denominator: T})",
         .documentation =
         \\Floored division. Rounds toward negative infinity. For unsigned integers it is the same as `numerator / denominator`. Caller guarantees `denominator != 0` and `!(@typeInfo(T) == .Int and T.is_signed and numerator == std.math.minInt(T) and denominator == -1)`.
-        \\  - `@divFloor(-5, 3) == -2`
-        \\  - `(@divFloor(a, b) * b) + @mod(a, b) == a`
         \\
+        \\ - `@divFloor(-5, 3) == -2`
+        \\ - `(@divFloor(a, b) * b) + @mod(a, b) == a`
         \\For a function that returns a possible error code, use `@import("std").math.divFloor`.
         ,
         .arguments = &.{
@@ -556,9 +622,9 @@ pub const builtins = [_]Builtin{
         .snippet = "@divTrunc(${1:numerator: T}, ${2:denominator: T})",
         .documentation =
         \\Truncated division. Rounds toward zero. For unsigned integers it is the same as `numerator / denominator`. Caller guarantees `denominator != 0` and `!(@typeInfo(T) == .Int and T.is_signed and numerator == std.math.minInt(T) and denominator == -1)`.
-        \\  - `@divTrunc(-5, 3) == -1`
-        \\  - `(@divTrunc(a, b) * b) + @rem(a, b) == a`
         \\
+        \\ - `@divTrunc(-5, 3) == -1`
+        \\ - `(@divTrunc(a, b) * b) + @rem(a, b) == a`
         \\For a function that returns a possible error code, use `@import("std").math.divTrunc`.
         ,
         .arguments = &.{
@@ -568,10 +634,10 @@ pub const builtins = [_]Builtin{
     },
     .{
         .name = "@embedFile",
-        .signature = "@embedFile(comptime path: []const u8) *const [N:0]u8",
+        .signature = "@embedFile(comptime path: []const u8) *const [X:0]u8",
         .snippet = "@embedFile(${1:comptime path: []const u8})",
         .documentation =
-        \\This function returns a compile time constant pointer to null-terminated, fixed-size array with length equal to the byte count of the file given by `path`. The contents of the array are the contents of the file. This is equivalent to a [string literal](https://ziglang.org/documentation/master/#String-Literals-and-Unicode-Code-Point-Literals) with the file contents.
+        \\This function returns a compile time constant pointer to null-terminated, fixed-size array with length equal to the byte count of the file given by `path`. The contents of the array are the contents of the file. This is equivalent to a [string literal](https://ziglang.org/documentation/0.8.1/#String-Literals-and-Unicode-Code-Point-Literals) with the file contents.
         \\
         \\`path` is absolute or relative to the current file, just like `@import`.
         ,
@@ -586,7 +652,7 @@ pub const builtins = [_]Builtin{
         .documentation =
         \\Converts an enumeration value into its integer tag type. When a tagged union is passed, the tag value is used as the enumeration value.
         \\
-        \\If there is only one possible enum value, the result is a `comptime_int` known at [comptime](https://ziglang.org/documentation/master/#comptime).
+        \\If there is only one possible enum value, the resut is a `comptime_int` known at [comptime](https://ziglang.org/documentation/0.8.1/#comptime).
         ,
         .arguments = &.{
             "enum_or_tagged_union: anytype",
@@ -594,7 +660,7 @@ pub const builtins = [_]Builtin{
     },
     .{
         .name = "@errorName",
-        .signature = "@errorName(err: anyerror) [:0]const u8",
+        .signature = "@errorName(err: anyerror) []const u8",
         .snippet = "@errorName(${1:err: anyerror})",
         .documentation =
         \\This function returns the string representation of an error. The string representation of `error.OutOfMem` is `"OutOfMem"`.
@@ -610,7 +676,7 @@ pub const builtins = [_]Builtin{
         .signature = "@errorReturnTrace() ?*builtin.StackTrace",
         .snippet = "@errorReturnTrace()",
         .documentation =
-        \\If the binary is built with error return tracing, and this function is invoked in a function that calls a function with an error or error union return type, returns a stack trace object. Otherwise returns [null](https://ziglang.org/documentation/master/#null).
+        \\If the binary is built with error return tracing, and this function is invoked in a function that calls a function with an error or error union return type, returns a stack trace object. Otherwise returns [null](https://ziglang.org/documentation/0.8.1/#null).
         ,
         .arguments = &.{},
     },
@@ -620,10 +686,10 @@ pub const builtins = [_]Builtin{
         .snippet = "@errorToInt(${1:err: anytype})",
         .documentation =
         \\Supports the following types:
-        \\  - [The Global Error Set](https://ziglang.org/documentation/master/#The-Global-Error-Set)
-        \\  - [Error Set Type](https://ziglang.org/documentation/master/#Error-Set-Type)
-        \\  - [Error Union Type](https://ziglang.org/documentation/master/#Error-Union-Type)
         \\
+        \\ - [The Global Error Set](https://ziglang.org/documentation/0.8.1/#The-Global-Error-Set)
+        \\ - [Error Set Type](https://ziglang.org/documentation/0.8.1/#Error-Set-Type)
+        \\ - [Error Union Type](https://ziglang.org/documentation/0.8.1/#Error-Union-Type)
         \\Converts an error to the integer representation of an error.
         \\
         \\It is generally recommended to avoid this cast, as the integer representation of an error is not stable across source code changes.
@@ -637,7 +703,7 @@ pub const builtins = [_]Builtin{
         .signature = "@errSetCast(comptime T: DestType, value: anytype) DestType",
         .snippet = "@errSetCast(${1:comptime T: DestType}, ${2:value: anytype})",
         .documentation =
-        \\Converts an error value from one error set to another error set. Attempting to convert an error which is not in the destination error set results in safety-protected [Undefined Behavior](https://ziglang.org/documentation/master/#Undefined-Behavior).
+        \\Converts an error value from one error set to another error set. Attempting to convert an error which is not in the destination error set results in safety-protected [Undefined Behavior](https://ziglang.org/documentation/0.8.1/#Undefined-Behavior).
         ,
         .arguments = &.{
             "comptime T: DestType",
@@ -646,45 +712,31 @@ pub const builtins = [_]Builtin{
     },
     .{
         .name = "@export",
-        .signature = "@export(declaration, comptime options: std.builtin.ExportOptions) void",
-        .snippet = "@export(${1:declaration}, ${2:comptime options: std.builtin.ExportOptions})",
+        .signature = "@export(identifier, comptime options: std.builtin.ExportOptions) void",
+        .snippet = "@export(${1:identifier}, ${2:comptime options: std.builtin.ExportOptions})",
         .documentation =
         \\Creates a symbol in the output object file.
         \\
-        \\`declaration` must be one of two things:
-        \\  - An identifier (`x`) identifying a [function](https://ziglang.org/documentation/master/#Functions) or a [variable](https://ziglang.org/documentation/master/#Container-Level-Variables).
-        \\  - Field access (`x.y`) looking up a [function](https://ziglang.org/documentation/master/#Functions) or a [variable](https://ziglang.org/documentation/master/#Container-Level-Variables).
-        \\
-        \\This builtin can be called from a [comptime](https://ziglang.org/documentation/master/#comptime) block to conditionally export symbols. When `declaration` is a function with the C calling convention and `options.linkage` is `Strong`, this is equivalent to the `export` keyword used on a function:
+        \\This function can be called from a [comptime](https://ziglang.org/documentation/0.8.1/#comptime) block to conditionally export symbols. When `identifier` is a function with the C calling convention and `options.linkage` is `Strong`, this is equivalent to the `export` keyword used on a function:
         \\
         \\```zig
         \\comptime {
         \\    @export(internalName, .{ .name = "foo", .linkage = .Strong });
         \\}
-        \\
         \\fn internalName() callconv(.C) void {}
         \\```
-        \\
         \\This is equivalent to:
         \\
-        \\```zig
-        \\export fn foo() void {}
-        \\```
-        \\
+        \\`export fn foo() void {}`
         \\Note that even when using `export`, `@"foo"` syntax can be used to choose any string for the symbol name:
         \\
-        \\```zig
-        \\export fn @"A function name that is a complete sentence."() void {}
-        \\```
-        \\
+        \\`export fn @"A function name that is a complete sentence."() void {}`
         \\When looking at the resulting object, you can see the symbol is used verbatim:
         \\
-        \\```zig
-        \\00000000000001f0 T A function name that is a complete sentence.
-        \\```
+        \\`00000000000001f0 T A function name that is a complete sentence.`
         ,
         .arguments = &.{
-            "declaration",
+            "identifier",
             "comptime options: std.builtin.ExportOptions",
         },
     },
@@ -718,7 +770,30 @@ pub const builtins = [_]Builtin{
         .signature = "@field(lhs: anytype, comptime field_name: []const u8) (field)",
         .snippet = "@field(${1:lhs: anytype}, ${2:comptime field_name: []const u8})",
         .documentation =
-        \\Performs field access by a compile-time string. Works on both fields and declarations.

{#code_begin|test|field_decl_access_by_string#} const std = @import("std"); const Point = struct { x: u32, y: u32, pub var z: u32 = 1; }; test "field access by string" { const expect = std.testing.expect; var p = Point{ .x = 0, .y = 0 }; @field(p, "x") = 4; @field(p, "y") = @field(p, "x") + 1; try expect(@field(p, "x") == 4); try expect(@field(p, "y") == 5); } test "decl access by string" { const expect = std.testing.expect; try expect(@field(Point, "z") == 1); @field(Point, "z") = 2; try expect(@field(Point, "z") == 2); }`
+        \\Performs field access by a compile-time string. Works on both fields and declarations.
+        \\
+        \\```zig
+        \\const std = @import("std");
+        \\const Point = struct {
+        \\    x: u32,
+        \\    y: u32,
+        \\    pub var z: u32 = 1;
+        \\};
+        \\test "field access by string" {
+        \\    const expect = std.testing.expect;
+        \\    var p = Point{ .x = 0, .y = 0 };
+        \\    @field(p, "x") = 4;
+        \\    @field(p, "y") = @field(p, "x") + 1;
+        \\    try expect(@field(p, "x") == 4);
+        \\    try expect(@field(p, "y") == 5);
+        \\}
+        \\test "decl access by string" {
+        \\    const expect = std.testing.expect;
+        \\    try expect(@field(Point, "z") == 1);
+        \\    @field(Point, "z") = 2;
+        \\    try expect(@field(Point, "z") == 2);
+        \\}
+        \\```
         ,
         .arguments = &.{
             "lhs: anytype",
@@ -727,7 +802,7 @@ pub const builtins = [_]Builtin{
     },
     .{
         .name = "@fieldParentPtr",
-        .signature = "@fieldParentPtr(comptime ParentType: type, comptime field_name: []const u8, field_ptr: *T) *ParentType",
+        .signature = "@fieldParentPtr(comptime ParentType: type, comptime field_name: []const u8,    field_ptr: *T) *ParentType",
         .snippet = "@fieldParentPtr(${1:comptime ParentType: type}, ${2:comptime field_name: []const u8}, ${3:field_ptr: *T})",
         .documentation =
         \\Given a pointer to a field, returns the base pointer of a struct.
@@ -757,7 +832,7 @@ pub const builtins = [_]Builtin{
         .documentation =
         \\Converts the integer part of a floating point number to the destination type.
         \\
-        \\If the integer part of the floating point number cannot fit in the destination type, it invokes safety-checked [Undefined Behavior](https://ziglang.org/documentation/master/#Undefined-Behavior).
+        \\If the integer part of the floating point number cannot fit in the destination type, it invokes safety-checked [Undefined Behavior](https://ziglang.org/documentation/0.8.1/#Undefined-Behavior).
         ,
         .arguments = &.{
             "comptime DestType: type",
@@ -769,9 +844,9 @@ pub const builtins = [_]Builtin{
         .signature = "@frame() *@Frame(func)",
         .snippet = "@frame()",
         .documentation =
-        \\This function returns a pointer to the frame for a given function. This type can be [coerced](https://ziglang.org/documentation/master/#Type-Coercion) to `anyframe->T` and to `anyframe`, where `T` is the return type of the function in scope.
+        \\This function returns a pointer to the frame for a given function. This type can be [coerced](https://ziglang.org/documentation/0.8.1/#Type-Coercion) to `anyframe->T` and to `anyframe`, where `T` is the return type of the function in scope.
         \\
-        \\This function does not mark a suspension point, but it does cause the function in scope to become an [async function](https://ziglang.org/documentation/master/#Async-Functions).
+        \\This function does not mark a suspension point, but it does cause the function in scope to become an [async function](https://ziglang.org/documentation/0.8.1/#Async-Functions).
         ,
         .arguments = &.{},
     },
@@ -780,9 +855,20 @@ pub const builtins = [_]Builtin{
         .signature = "@Frame(func: anytype) type",
         .snippet = "@Frame(${1:func: anytype})",
         .documentation =
-        \\This function returns the frame type of a function. This works for [Async Functions](https://ziglang.org/documentation/master/#Async-Functions) as well as any function without a specific calling convention.
+        \\This function returns the frame type of a function. This works for [Async Functions](https://ziglang.org/documentation/0.8.1/#Async-Functions) as well as any function without a specific calling convention.
         \\
-        \\This type is suitable to be used as the return type of [async](https://ziglang.org/documentation/master/#Async-and-Await) which allows one to, for example, heap-allocate an async function frame:

{#code_begin|test|heap_allocated_frame#} const std = @import("std"); test "heap allocated frame" { const frame = try std.heap.page_allocator.create(@Frame(func)); frame.* = async func(); } fn func() void { suspend {} }`
+        \\This type is suitable to be used as the return type of [async](https://ziglang.org/documentation/0.8.1/#Async-and-Await) which allows one to, for example, heap-allocate an async function frame:
+        \\
+        \\```zig
+        \\const std = @import("std");
+        \\test "heap allocated frame" {
+        \\    const frame = try std.heap.page_allocator.create(@Frame(func));
+        \\    frame.* = async func();
+        \\}
+        \\fn func() void {
+        \\    suspend {}
+        \\}
+        \\```
         ,
         .arguments = &.{
             "func: anytype",
@@ -808,7 +894,7 @@ pub const builtins = [_]Builtin{
         .documentation =
         \\This is the same as `@sizeOf(@Frame(func))`, where `func` may be runtime-known.
         \\
-        \\This function is typically used in conjunction with [@asyncCall](https://ziglang.org/documentation/master/#asyncCall).
+        \\This function is typically used in conjunction with [@asyncCall](https://ziglang.org/documentation/0.8.1/#asyncCall).
         ,
         .arguments = &.{},
     },
@@ -817,8 +903,27 @@ pub const builtins = [_]Builtin{
         .signature = "@hasDecl(comptime Container: type, comptime name: []const u8) bool",
         .snippet = "@hasDecl(${1:comptime Container: type}, ${2:comptime name: []const u8})",
         .documentation =
-        \\Returns whether or not a [struct](https://ziglang.org/documentation/master/#struct), [enum](https://ziglang.org/documentation/master/#enum), or [union](https://ziglang.org/documentation/master/#union) has a declaration matching `name`.

{#code_begin|test|hasDecl#} const std = @import("std"); const expect = std.testing.expect; const Foo = struct { nope: i32, pub var blah = "xxx"; const hi = 1; }; test "@hasDecl" { try expect(@hasDecl(Foo, "blah")); // Even though `hi` is private, @hasDecl returns true because this test is // in the same file scope as Foo. It would return false if Foo was declared // in a different file. try expect(@hasDecl(Foo, "hi")); // @hasDecl is for declarations; not fields. try expect(!@hasDecl(Foo, "nope")); try expect(!@hasDecl(Foo, "nope1234")); }`
-        \\      
+        \\Returns whether or not a [struct](https://ziglang.org/documentation/0.8.1/#struct), [enum](https://ziglang.org/documentation/0.8.1/#enum), or [union](https://ziglang.org/documentation/0.8.1/#union) has a declaration matching `name`.
+        \\
+        \\```zig
+        \\const std = @import("std");
+        \\const expect = std.testing.expect;
+        \\const Foo = struct {
+        \\    nope: i32,
+        \\    pub var blah = "xxx";
+        \\    const hi = 1;
+        \\};
+        \\test "@hasDecl" {
+        \\    try expect(@hasDecl(Foo, "blah"));
+        \\    // Even though `hi` is private, @hasDecl returns true because this test is
+        \\    // in the same file scope as Foo. It would return false if Foo was declared
+        \\    // in a different file.
+        \\    try expect(@hasDecl(Foo, "hi"));
+        \\    // @hasDecl is for declarations; not fields.
+        \\    try expect(!@hasDecl(Foo, "nope"));
+        \\    try expect(!@hasDecl(Foo, "nope1234"));
+        \\}
+        \\```
         ,
         .arguments = &.{
             "comptime Container: type",
@@ -855,8 +960,10 @@ pub const builtins = [_]Builtin{
         \\`path` can be a relative path or it can be the name of a package. If it is a relative path, it is relative to the file that contains the `@import` function call.
         \\
         \\The following packages are always available:
-        \\  - `@import("std")` - Zig Standard Library
-        \\  - `@import("builtin")` - Target-specific information The command `zig build-exe --show-builtin` outputs the source to stdout for reference.
+        \\
+        \\ - `@import("std")` - Zig Standard Library
+        \\ - `@import("builtin")` - Target-specific information The command
+        \\`zig build-exe --show-builtin`outputs the source to stdout for reference.
         ,
         .arguments = &.{
             "comptime path: []u8",
@@ -867,9 +974,9 @@ pub const builtins = [_]Builtin{
         .signature = "@intCast(comptime DestType: type, int: anytype) DestType",
         .snippet = "@intCast(${1:comptime DestType: type}, ${2:int: anytype})",
         .documentation =
-        \\Converts an integer to another integer while keeping the same numerical value. Attempting to convert a number which is out of range of the destination type results in safety-protected [Undefined Behavior](https://ziglang.org/documentation/master/#Undefined-Behavior).
+        \\Converts an integer to another integer while keeping the same numerical value. Attempting to convert a number which is out of range of the destination type results in safety-protected [Undefined Behavior](https://ziglang.org/documentation/0.8.1/#Undefined-Behavior).
         \\
-        \\If `T` is `comptime_int`, then this is semantically equivalent to [Type Coercion](https://ziglang.org/documentation/master/#Type-Coercion).
+        \\If `T` is `comptime_int`, then this is semantically equivalent to [Type Coercion](https://ziglang.org/documentation/0.8.1/#Type-Coercion).
         ,
         .arguments = &.{
             "comptime DestType: type",
@@ -878,31 +985,31 @@ pub const builtins = [_]Builtin{
     },
     .{
         .name = "@intToEnum",
-        .signature = "@intToEnum(comptime DestType: type, integer: anytype) DestType",
-        .snippet = "@intToEnum(${1:comptime DestType: type}, ${2:integer: anytype})",
+        .signature = "@intToEnum(comptime DestType: type, int_value: std.meta.Tag(DestType)) DestType",
+        .snippet = "@intToEnum(${1:comptime DestType: type}, ${2:int_value: std.meta.Tag(DestType)})",
         .documentation =
-        \\Converts an integer into an [enum](https://ziglang.org/documentation/master/#enum) value.
+        \\Converts an integer into an [enum](https://ziglang.org/documentation/0.8.1/#enum) value.
         \\
-        \\Attempting to convert an integer which represents no value in the chosen enum type invokes safety-checked [Undefined Behavior](https://ziglang.org/documentation/master/#Undefined-Behavior).
+        \\Attempting to convert an integer which represents no value in the chosen enum type invokes safety-checked [Undefined Behavior](https://ziglang.org/documentation/0.8.1/#Undefined-Behavior).
         ,
         .arguments = &.{
             "comptime DestType: type",
-            "integer: anytype",
+            "int_value: std.meta.Tag(DestType)",
         },
     },
     .{
         .name = "@intToError",
         .signature = "@intToError(value: std.meta.Int(.unsigned, @sizeOf(anyerror) * 8)) anyerror",
-        .snippet = "@intToError(${1:value: std.meta.Int(.unsigned, @sizeOf(anyerror) * 8)})",
+        .snippet = "@intToError(${1:value: std.meta.Int(.unsigned, @sizeOf(anyerror) * 8})",
         .documentation =
-        \\Converts from the integer representation of an error into [The Global Error Set](https://ziglang.org/documentation/master/#The-Global-Error-Set) type.
+        \\Converts from the integer representation of an error into [The Global Error Set](https://ziglang.org/documentation/0.8.1/#The-Global-Error-Set) type.
         \\
         \\It is generally recommended to avoid this cast, as the integer representation of an error is not stable across source code changes.
         \\
-        \\Attempting to convert an integer that does not correspond to any error results in safety-protected [Undefined Behavior](https://ziglang.org/documentation/master/#Undefined-Behavior).
+        \\Attempting to convert an integer that does not correspond to any error results in safety-protected [Undefined Behavior](https://ziglang.org/documentation/0.8.1/#Undefined-Behavior).
         ,
         .arguments = &.{
-            "value: std.meta.Int(.unsigned, @sizeOf(anyerror) * 8)",
+            "value: std.meta.Int(.unsigned, @sizeOf(anyerror) * 8",
         },
     },
     .{
@@ -910,7 +1017,7 @@ pub const builtins = [_]Builtin{
         .signature = "@intToFloat(comptime DestType: type, int: anytype) DestType",
         .snippet = "@intToFloat(${1:comptime DestType: type}, ${2:int: anytype})",
         .documentation =
-        \\Converts an integer to the closest floating point representation. To convert the other way, use [@floatToInt](https://ziglang.org/documentation/master/#floatToInt). This cast is always safe.
+        \\Converts an integer to the closest floating point representation. To convert the other way, use [@floatToInt](https://ziglang.org/documentation/0.8.1/#floatToInt). This cast is always safe.
         ,
         .arguments = &.{
             "comptime DestType: type",
@@ -922,29 +1029,15 @@ pub const builtins = [_]Builtin{
         .signature = "@intToPtr(comptime DestType: type, address: usize) DestType",
         .snippet = "@intToPtr(${1:comptime DestType: type}, ${2:address: usize})",
         .documentation =
-        \\Converts an integer to a [pointer](https://ziglang.org/documentation/master/#Pointers). To convert the other way, use [@ptrToInt](https://ziglang.org/documentation/master/#ptrToInt).
+        \\Converts an integer to a [pointer](https://ziglang.org/documentation/0.8.1/#Pointers). To convert the other way, use [@ptrToInt](https://ziglang.org/documentation/0.8.1/#ptrToInt).
         \\
-        \\If the destination pointer type does not allow address zero and `address` is zero, this invokes safety-checked [Undefined Behavior](https://ziglang.org/documentation/master/#Undefined-Behavior).
+        \\If the destination pointer type does not allow address zero and `address` is zero, this invokes safety-checked [Undefined Behavior](https://ziglang.org/documentation/0.8.1/#Undefined-Behavior).
         ,
         .arguments = &.{
             "comptime DestType: type",
             "address: usize",
         },
     },
-    .{
-        .name = "@maximum",
-        .signature = "@maximum(a: T, b: T) T",
-        .snippet = "@maximum(${1:a: T}, ${2:b: T})",
-        .documentation =
-        \\Returns the maximum value of `a` and `b`. This builtin accepts integers, floats, and vectors of either. In the latter case, the operation is performed element wise.
-        \\
-        \\NaNs are handled as follows: if one of the operands of a (pairwise) operation is NaN, the other operand is returned. If both operands are NaN, NaN is returned.
-        ,
-        .arguments = &.{
-            "a: T",
-            "b: T",
-        },
-    },
     .{
         .name = "@memcpy",
         .signature = "@memcpy(noalias dest: [*]u8, noalias source: [*]const u8, byte_count: usize)",
@@ -954,10 +1047,7 @@ pub const builtins = [_]Builtin{
         \\
         \\This function is a low level intrinsic with no safety mechanisms. Most code should not use this function, instead using something like this:
         \\
-        \\```zig
-        \\for (source[0..byte_count]) |b, i| dest[i] = b;
-        \\```
-        \\
+        \\`for (source[0..byte_count]) |b, i| dest[i] = b;`
         \\The optimizer is intelligent enough to turn the above snippet into a memcpy.
         \\
         \\There is also a standard library function for this:
@@ -982,10 +1072,7 @@ pub const builtins = [_]Builtin{
         \\
         \\This function is a low level intrinsic with no safety mechanisms. Most code should not use this function, instead using something like this:
         \\
-        \\```zig
-        \\for (dest[0..byte_count]) |*b| b.* = c;
-        \\```
-        \\
+        \\`for (dest[0..byte_count]) |*b| b.* = c;`
         \\The optimizer is intelligent enough to turn the above snippet into a memset.
         \\
         \\There is also a standard library function for this:
@@ -1001,20 +1088,6 @@ pub const builtins = [_]Builtin{
             "byte_count: usize",
         },
     },
-    .{
-        .name = "@minimum",
-        .signature = "@minimum(a: T, b: T) T",
-        .snippet = "@minimum(${1:a: T}, ${2:b: T})",
-        .documentation =
-        \\Returns the minimum value of `a` and `b`. This builtin accepts integers, floats, and vectors of either. In the latter case, the operation is performed element wise.
-        \\
-        \\NaNs are handled as follows: if one of the operands of a (pairwise) operation is NaN, the other operand is returned. If both operands are NaN, NaN is returned.
-        ,
-        .arguments = &.{
-            "a: T",
-            "b: T",
-        },
-    },
     .{
         .name = "@wasmMemorySize",
         .signature = "@wasmMemorySize(index: u32) u32",
@@ -1035,8 +1108,19 @@ pub const builtins = [_]Builtin{
         .documentation =
         \\This function increases the size of the Wasm memory identified by `index` by `delta` in units of unsigned number of Wasm pages. Note that each Wasm page is 64KB in size. On success, returns previous memory size; on failure, if the allocation fails, returns -1.
         \\
-        \\This function is a low level intrinsic with no safety mechanisms usually useful for allocator designers targeting Wasm. So unless you are writing a new allocator from scratch, you should use something like `@import("std").heap.WasmPageAllocator`.

{#code_begin|test|wasmMemoryGrow#} const std = @import("std"); const native_arch = @import("builtin").target.cpu.arch; const expect = std.testing.expect; test "@wasmMemoryGrow" { if (native_arch != .wasm32) return error.SkipZigTest; var prev = @wasmMemorySize(0); try expect(prev == @wasmMemoryGrow(0, 1)); try expect(prev + 1 == @wasmMemorySize(0)); }`
-        \\      
+        \\This function is a low level intrinsic with no safety mechanisms usually useful for allocator designers targeting Wasm. So unless you are writing a new allocator from scratch, you should use something like `@import("std").heap.WasmPageAllocator`.
+        \\
+        \\```zig
+        \\const std = @import("std");
+        \\const native_arch = @import("builtin").target.cpu.arch;
+        \\const expect = std.testing.expect;
+        \\test "@wasmMemoryGrow" {
+        \\    if (native_arch != .wasm32) return error.SkipZigTest;
+        \\    var prev = @wasmMemorySize(0);
+        \\    try expect(prev == @wasmMemoryGrow(0, 1));
+        \\    try expect(prev + 1 == @wasmMemorySize(0));
+        \\}
+        \\```
         ,
         .arguments = &.{
             "index: u32",
@@ -1049,9 +1133,9 @@ pub const builtins = [_]Builtin{
         .snippet = "@mod(${1:numerator: T}, ${2:denominator: T})",
         .documentation =
         \\Modulus division. For unsigned integers this is the same as `numerator % denominator`. Caller guarantees `denominator > 0`.
-        \\  - `@mod(-5, 3) == 1`
-        \\  - `(@divFloor(a, b) * b) + @mod(a, b) == a`
         \\
+        \\ - `@mod(-5, 3) == 1`
+        \\ - `(@divFloor(a, b) * b) + @mod(a, b) == a`
         \\For a function that returns an error code, see `@import("std").math.mod`.
         ,
         .arguments = &.{
@@ -1081,8 +1165,9 @@ pub const builtins = [_]Builtin{
         \\Invokes the panic handler function. By default the panic handler function calls the public `panic` function exposed in the root source file, or if there is not one specified, the `std.builtin.default_panic` function from `std/builtin.zig`.
         \\
         \\Generally it is better to use `@import("std").debug.panic`. However, `@panic` can be useful for 2 scenarios:
-        \\  - From library code, calling the programmer's panic function if they exposed one in the root source file.
-        \\  - When mixing C and Zig code, calling the canonical panic implementation across multiple .o files.
+        \\
+        \\ - From library code, calling the programmer's panic function if they exposed one in the root source file.
+        \\ - When mixing C and Zig code, calling the canonical panic implementation across multiple .o files.
         ,
         .arguments = &.{
             "message: []const u8",
@@ -1090,20 +1175,16 @@ pub const builtins = [_]Builtin{
     },
     .{
         .name = "@popCount",
-        .signature = "@popCount(comptime T: type, operand: T)",
-        .snippet = "@popCount(${1:comptime T: type}, ${2:operand: T})",
+        .signature = "@popCount(comptime T: type, integer: T)",
+        .snippet = "@popCount(${1:comptime T: type}, ${2:integer: T})",
         .documentation =
-        \\`T` must be an integer type.
-        \\
-        \\`operand` may be an [integer](https://ziglang.org/documentation/master/#Integers) or [vector](https://ziglang.org/documentation/master/#Vectors).
-        \\
         \\Counts the number of bits set in an integer.
         \\
-        \\If `operand` is a [comptime](https://ziglang.org/documentation/master/#comptime)-known integer, the return type is `comptime_int`. Otherwise, the return type is an unsigned integer or vector of unsigned integers with the minimum number of bits that can represent the bit count of the integer type.
+        \\If `integer` is known at [comptime](https://ziglang.org/documentation/0.8.1/#comptime), the return type is `comptime_int`. Otherwise, the return type is an unsigned integer with the minimum number of bits that can represent the bit count of the integer type.
         ,
         .arguments = &.{
             "comptime T: type",
-            "operand: T",
+            "integer: T",
         },
     },
     .{
@@ -1113,7 +1194,7 @@ pub const builtins = [_]Builtin{
         .documentation =
         \\Converts a pointer of one type to a pointer of another type.
         \\
-        \\[Optional Pointers](https://ziglang.org/documentation/master/#Optional-Pointers) are allowed. Casting an optional pointer which is [null](https://ziglang.org/documentation/master/#null) to a non-optional pointer invokes safety-checked [Undefined Behavior](https://ziglang.org/documentation/master/#Undefined-Behavior).
+        \\[Optional Pointers](https://ziglang.org/documentation/0.8.1/#Optional-Pointers) are allowed. Casting an optional pointer which is [null](https://ziglang.org/documentation/0.8.1/#null) to a non-optional pointer invokes safety-checked [Undefined Behavior](https://ziglang.org/documentation/0.8.1/#Undefined-Behavior).
         ,
         .arguments = &.{
             "comptime DestType: type",
@@ -1126,12 +1207,12 @@ pub const builtins = [_]Builtin{
         .snippet = "@ptrToInt(${1:value: anytype})",
         .documentation =
         \\Converts `value` to a `usize` which is the address of the pointer. `value` can be one of these types:
-        \\  - `*T`
-        \\  - `?*T`
-        \\  - `fn()`
-        \\  - `?fn()`
         \\
-        \\To convert the other way, use [@intToPtr](https://ziglang.org/documentation/master/#intToPtr)
+        \\ - `*T`
+        \\ - `?*T`
+        \\ - `fn()`
+        \\ - `?fn()`
+        \\To convert the other way, use [@intToPtr](https://ziglang.org/documentation/0.8.1/#intToPtr)
         ,
         .arguments = &.{
             "value: anytype",
@@ -1143,9 +1224,9 @@ pub const builtins = [_]Builtin{
         .snippet = "@rem(${1:numerator: T}, ${2:denominator: T})",
         .documentation =
         \\Remainder division. For unsigned integers this is the same as `numerator % denominator`. Caller guarantees `denominator > 0`.
-        \\  - `@rem(-5, 3) == -2`
-        \\  - `(@divTrunc(a, b) * b) + @rem(a, b) == a`
         \\
+        \\ - `@rem(-5, 3) == -2`
+        \\ - `(@divTrunc(a, b) * b) + @rem(a, b) == a`
         \\For a function that returns an error code, see `@import("std").math.rem`.
         ,
         .arguments = &.{
@@ -1166,20 +1247,6 @@ pub const builtins = [_]Builtin{
         ,
         .arguments = &.{},
     },
-    .{
-        .name = "@select",
-        .signature = "@select(comptime T: type, pred: std.meta.Vector(len, bool), a: std.meta.Vector(len, T), b: std.meta.Vector(len, T)) std.meta.Vector(len, T)",
-        .snippet = "@select(${1:comptime T: type}, ${2:pred: std.meta.Vector(len, bool)}, ${3:a: std.meta.Vector(len, T)}, ${4:b: std.meta.Vector(len, T)})",
-        .documentation =
-        \\Selects values element-wise from `a` or `b` based on `pred`. If `pred[i]` is `true`, the corresponding element in the result will be `a[i]` and otherwise `b[i]`.
-        ,
-        .arguments = &.{
-            "comptime T: type",
-            "pred: std.meta.Vector(len, bool)",
-            "a: std.meta.Vector(len, T)",
-            "b: std.meta.Vector(len, T)",
-        },
-    },
     .{
         .name = "@setAlignStack",
         .signature = "@setAlignStack(comptime alignment: u29)",
@@ -1213,18 +1280,16 @@ pub const builtins = [_]Builtin{
         \\
         \\Example:
         \\
-        \\```zig
-        \\test "foo" {
-        \\    comptime {
-        \\        var i = 0;
-        \\        while (i < 1001) : (i += 1) {}
+        \\1001) : (i += 1) {}
         \\    }
         \\}
         \\```
+        \\Now we use `@setEvalBranchQuota`:
         \\
-        \\Now we use `@setEvalBranchQuota`:

{#code_begin|test|setEvalBranchQuota#} test "foo" { comptime { @setEvalBranchQuota(1001); var i = 0; while (i < 1001) : (i += 1) {} } }`
-        \\
-        \\      
+        \\1001) : (i += 1) {}
+        \\    }
+        \\}
+        \\```
         ,
         .arguments = &.{
             "new_quota: u32",
@@ -1243,16 +1308,16 @@ pub const builtins = [_]Builtin{
         \\    Optimized,
         \\};
         \\```
-        \\
-        \\  - `Strict` (default) - Floating point operations follow strict IEEE compliance.
-        \\  - `Optimized` - Floating point operations may do all of the following: 
    - \\ - Assume the arguments and result are not NaN. Optimizations are required to retain defined behavior over NaNs, but the value of the result is undefined. - \\ - Assume the arguments and result are not +/-Inf. Optimizations are required to retain defined behavior over +/-Inf, but the value of the result is undefined. - \\ - Treat the sign of a zero argument or result as insignificant. - \\ - Use the reciprocal of an argument rather than perform division. - \\ - Perform floating-point contraction (e.g. fusing a multiply followed by an addition into a fused multiply-and-add). - \\ - Perform algebraically equivalent transformations that may change results in floating point (e.g. reassociate). This is equivalent to `-ffast-math` in GCC.
- \\ + \\ - `Strict` (default) - Floating point operations follow strict IEEE compliance. + \\ - `Optimized` - Floating point operations may do all of the following: + \\ - Assume the arguments and result are not NaN. Optimizations are required to retain defined behavior over NaNs, but the value of the result is undefined. + \\ - Assume the arguments and result are not +/-Inf. Optimizations are required to retain defined behavior over +/-Inf, but the value of the result is undefined. + \\ - Treat the sign of a zero argument or result as insignificant. + \\ - Use the reciprocal of an argument rather than perform division. + \\ - Perform floating-point contraction (e.g. fusing a multiply followed by an addition into a fused multiply-and-add). + \\ - Perform algebraically equivalent transformations that may change results in floating point (e.g. reassociate). + \\This is equivalent to + \\`-ffast-math`in GCC. \\The floating point mode is inherited by child scopes, and can be overridden in any scope. You can set the floating point mode in a struct or module scope by using a comptime block. , .arguments = &.{ @@ -1278,7 +1343,6 @@ pub const builtins = [_]Builtin{ \\ @setRuntimeSafety(true); \\ var x: u8 = 255; \\ x += 1; - \\ \\ { \\ // The value can be overridden at any scope. So here integer overflow \\ // would not be caught in any build mode. @@ -1289,8 +1353,9 @@ pub const builtins = [_]Builtin{ \\ } \\} \\``` - \\ - \\Note: it is [planned](https://github.com/ziglang/zig/issues/978) to replace `@setRuntimeSafety` with `@optimizeFor` + \\Note: it is + \\[planned](https://github.com/ziglang/zig/issues/978)to replace `@setRuntimeSafety` with + \\`@optimizeFor` , .arguments = &.{ "safety_on: bool", @@ -1301,7 +1366,7 @@ pub const builtins = [_]Builtin{ .signature = "@shlExact(value: T, shift_amt: Log2T) T", .snippet = "@shlExact(${1:value: T}, ${2:shift_amt: Log2T})", .documentation = - \\Performs the left shift operation (`<<`). For unsigned integers, the result is [undefined](https://ziglang.org/documentation/master/#undefined) if any 1 bits are shifted out. For signed integers, the result is [undefined](https://ziglang.org/documentation/master/#undefined) if any bits that disagree with the resultant sign bit are shifted out. + \\`). Caller guarantees that the shift will not shift any 1 bits out. \\ \\The type of `shift_amt` is an unsigned integer with `log2(T.bit_count)` bits. This is because `shift_amt >= T.bit_count` is undefined behavior. , @@ -1315,7 +1380,7 @@ pub const builtins = [_]Builtin{ .signature = "@shlWithOverflow(comptime T: type, a: T, shift_amt: Log2T, result: *T) bool", .snippet = "@shlWithOverflow(${1:comptime T: type}, ${2:a: T}, ${3:shift_amt: Log2T}, ${4:result: *T})", .documentation = - \\Performs `result.* = a << b`. If overflow or underflow occurs, stores the overflowed bits in `result` and returns `true`. If no overflow or underflow occurs, returns `false`. + \\b`. If overflow or underflow occurs, stores the overflowed bits in `result` and returns `true`. If no overflow or underflow occurs, returns `false`. \\ \\The type of `shift_amt` is an unsigned integer with `log2(T.bit_count)` bits. This is because `shift_amt >= T.bit_count` is undefined behavior. , @@ -1345,7 +1410,7 @@ pub const builtins = [_]Builtin{ .signature = "@shuffle(comptime E: type, a: std.meta.Vector(a_len, E), b: std.meta.Vector(b_len, E), comptime mask: std.meta.Vector(mask_len, i32)) std.meta.Vector(mask_len, E)", .snippet = "@shuffle(${1:comptime E: type}, ${2:a: std.meta.Vector(a_len, E)}, ${3:b: std.meta.Vector(b_len, E)}, ${4:comptime mask: std.meta.Vector(mask_len, i32)})", .documentation = - \\Constructs a new [vector](https://ziglang.org/documentation/master/#Vectors) by selecting elements from `a` and `b` based on `mask`. + \\Constructs a new [vector](https://ziglang.org/documentation/0.8.1/#Vectors) by selecting elements from `a` and `b` based on `mask`. \\ \\Each element in `mask` selects an element from either `a` or `b`. Positive numbers select from `a` starting at 0. Negative values select from `b`, starting at `-1` and going down. It is recommended to use the `~` operator from indexes from `b` so that both indexes can start from `0` (i.e. `~@as(i32, 0)` is `-1`). \\ @@ -1355,7 +1420,7 @@ pub const builtins = [_]Builtin{ \\ \\If `a` or `b` is `undefined`, it is equivalent to a vector of all `undefined` with the same length as the other vector. If both vectors are `undefined`, `@shuffle` returns a vector with all elements `undefined`. \\ - \\`E` must be an [integer](https://ziglang.org/documentation/master/#Integers), [float](https://ziglang.org/documentation/master/#Floats), [pointer](https://ziglang.org/documentation/master/#Pointers), or `bool`. The mask may be any vector length, and its length determines the result length. + \\`E` must be an [integer](https://ziglang.org/documentation/0.8.1/#Integers), [float](https://ziglang.org/documentation/0.8.1/#Floats), [pointer](https://ziglang.org/documentation/0.8.1/#Pointers), or `bool`. The mask may be any vector length, and its length determines the result length. , .arguments = &.{ "comptime E: type", @@ -1371,7 +1436,7 @@ pub const builtins = [_]Builtin{ .documentation = \\This function returns the number of bytes it takes to store `T` in memory. The result is a target-specific compile time constant. \\ - \\This size may contain padding bytes. If there were two consecutive T in memory, this would be the offset in bytes between element at index 0 and the element at index 1. For [integer](https://ziglang.org/documentation/master/#Integers), consider whether you want to use `@sizeOf(T)` or `@typeInfo(T).Int.bits`. + \\This size may contain padding bytes. If there were two consecutive T in memory, this would be the offset in bytes between element at index 0 and the element at index 1. For [integer](https://ziglang.org/documentation/0.8.1/#Integers), consider whether you want to use `@sizeOf(T)` or `@typeInfo(T).Int.bits`. \\ \\This function measures the size at runtime. For types that are disallowed at runtime, such as `comptime_int` and `type`, the result is `0`. , @@ -1384,14 +1449,19 @@ pub const builtins = [_]Builtin{ .signature = "@splat(comptime len: u32, scalar: anytype) std.meta.Vector(len, @TypeOf(scalar))", .snippet = "@splat(${1:comptime len: u32}, ${2:scalar: anytype})", .documentation = - \\Produces a vector of length `len` where each element is the value `scalar`:

{#code_begin|test|vector_splat#} const std = @import("std"); const expect = std.testing.expect; test "vector @splat" { const scalar: u32 = 5; const result = @splat(4, scalar); comptime try expect(@TypeOf(result) == std.meta.Vector(4, u32)); try expect(std.mem.eql(u32, &@as([4]u32, result), &[_]u32{ 5, 5, 5, 5 })); }`
-        \\      
+        \\Produces a vector of length `len` where each element is the value `scalar`:
         \\
-        \\
-        \\      `scalar` must be an [integer](https://ziglang.org/documentation/master/#Integers), [bool](https://ziglang.org/documentation/master/#Primitive-Types),
-        \\      [float](https://ziglang.org/documentation/master/#Floats), or [pointer](https://ziglang.org/documentation/master/#Pointers).
-        \\      

- \\ + \\```zig + \\const std = @import("std"); + \\const expect = std.testing.expect; + \\test "vector @splat" { + \\ const scalar: u32 = 5; + \\ const result = @splat(4, scalar); + \\ comptime try expect(@TypeOf(result) == std.meta.Vector(4, u32)); + \\ try expect(std.mem.eql(u32, &@as([4]u32, result), &[_]u32{ 5, 5, 5, 5 })); + \\} + \\``` + \\`scalar` must be an [integer](https://ziglang.org/documentation/0.8.1/#Integers), [bool](https://ziglang.org/documentation/0.8.1/#Primitive-Types), [float](https://ziglang.org/documentation/0.8.1/#Floats), or [pointer](https://ziglang.org/documentation/0.8.1/#Pointers). , .arguments = &.{ "comptime len: u32", @@ -1403,15 +1473,28 @@ pub const builtins = [_]Builtin{ .signature = "@reduce(comptime op: std.builtin.ReduceOp, value: anytype) std.meta.Child(value)", .snippet = "@reduce(${1:comptime op: std.builtin.ReduceOp}, ${2:value: anytype})", .documentation = - \\Transforms a [vector](https://ziglang.org/documentation/master/#Vectors) into a scalar value by performing a sequential horizontal reduction of its elements using the specified operator `op`. + \\Transforms a [vector](https://ziglang.org/documentation/0.8.1/#Vectors) into a scalar value by performing a sequential horizontal reduction of its elements using the specified operator `op`. \\ \\Not every operator is available for every vector element type: - \\ - `.And`, `.Or`, `.Xor` are available for `bool` vectors, - \\ - `.Min`, `.Max`, `.Add`, `.Mul` are available for [floating point](https://ziglang.org/documentation/master/#Floats) vectors, - \\ - Every operator is available for [integer](https://ziglang.org/documentation/master/#Integers) vectors. \\ - \\Note that `.Add` and `.Mul` reductions on integral types are wrapping; when applied on floating point types the operation associativity is preserved, unless the float mode is set to `Optimized`.

{#code_begin|test|vector_reduce#} const std = @import("std"); const expect = std.testing.expect; test "vector @reduce" { const value: std.meta.Vector(4, i32) = [_]i32{ 1, -1, 1, -1 }; const result = value > @splat(4, @as(i32, 0)); // result is { true, false, true, false }; comptime try expect(@TypeOf(result) == std.meta.Vector(4, bool)); const is_all_true = @reduce(.And, result); comptime try expect(@TypeOf(is_all_true) == bool); try expect(is_all_true == false); }`
-        \\      
+        \\ - `.And`, `.Or`, `.Xor` are available for `bool` vectors,
+        \\ - `.Min`, `.Max`, `.Add`, `.Mul` are available for [floating point](https://ziglang.org/documentation/0.8.1/#Floats) vectors,
+        \\ - Every operator is available for [integer](https://ziglang.org/documentation/0.8.1/#Integers) vectors.
+        \\Note that `.Add` and `.Mul` reductions on integral types are wrapping; when applied on floating point types the operation associativity is preserved, unless the float mode is set to `Optimized`.
+        \\
+        \\```zig
+        \\const std = @import("std");
+        \\const expect = std.testing.expect;
+        \\test "vector @reduce" {
+        \\    const value: std.meta.Vector(4, i32) = [_]i32{ 1, -1, 1, -1 };
+        \\    const result = value > @splat(4, @as(i32, 0));
+        \\    // result is { true, false, true, false };
+        \\    comptime try expect(@TypeOf(result) == std.meta.Vector(4, bool));
+        \\    const is_all_true = @reduce(.And, result);
+        \\    comptime try expect(@TypeOf(is_all_true) == bool);
+        \\    try expect(is_all_true == false);
+        \\}
+        \\```
         ,
         .arguments = &.{
             "comptime op: std.builtin.ReduceOp",
@@ -1423,7 +1506,22 @@ pub const builtins = [_]Builtin{
         .signature = "@src() std.builtin.SourceLocation",
         .snippet = "@src()",
         .documentation =
-        \\Returns a `SourceLocation` struct representing the function's name and location in the source code. This must be called in a function.

{#code_begin|test|source_location#} const std = @import("std"); const expect = std.testing.expect; test "@src" { try doTheTest(); } fn doTheTest() !void { const src = @src(); try expect(src.line == 9); try expect(src.column == 17); try expect(std.mem.endsWith(u8, src.fn_name, "doTheTest")); try expect(std.mem.endsWith(u8, src.file, "source_location.zig")); }`
+        \\Returns a `SourceLocation` struct representing the function's name and location in the source code. This must be called in a function.
+        \\
+        \\```zig
+        \\const std = @import("std");
+        \\const expect = std.testing.expect;
+        \\test "@src" {
+        \\    try doTheTest();
+        \\}
+        \\fn doTheTest() !void {
+        \\    const src = @src();
+        \\    try expect(src.line == 9);
+        \\    try expect(src.column == 17);
+        \\    try expect(std.mem.endsWith(u8, src.fn_name, "doTheTest"));
+        \\    try expect(std.mem.endsWith(u8, src.file, "test.zig"));
+        \\}
+        \\```
         ,
         .arguments = &.{},
     },
@@ -1434,7 +1532,8 @@ pub const builtins = [_]Builtin{
         .documentation =
         \\Performs the square root of a floating point number. Uses a dedicated hardware instruction when available.
         \\
-        \\Supports [Floats](https://ziglang.org/documentation/master/#Floats) and [Vectors](https://ziglang.org/documentation/master/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
+        \\Supports [Floats](https://ziglang.org/documentation/0.8.1/#Floats) and [Vectors](https://ziglang.org/documentation/0.8.1/#Vectors) of floats, with the caveat that
+        \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
         ,
         .arguments = &.{
             "value: anytype",
@@ -1445,9 +1544,10 @@ pub const builtins = [_]Builtin{
         .signature = "@sin(value: anytype) @TypeOf(value)",
         .snippet = "@sin(${1:value: anytype})",
         .documentation =
-        \\Sine trigonometric function on a floating point number. Uses a dedicated hardware instruction when available.
+        \\Sine trigometric function on a floating point number. Uses a dedicated hardware instruction when available.
         \\
-        \\Supports [Floats](https://ziglang.org/documentation/master/#Floats) and [Vectors](https://ziglang.org/documentation/master/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
+        \\Supports [Floats](https://ziglang.org/documentation/0.8.1/#Floats) and [Vectors](https://ziglang.org/documentation/0.8.1/#Vectors) of floats, with the caveat that
+        \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
         ,
         .arguments = &.{
             "value: anytype",
@@ -1458,9 +1558,10 @@ pub const builtins = [_]Builtin{
         .signature = "@cos(value: anytype) @TypeOf(value)",
         .snippet = "@cos(${1:value: anytype})",
         .documentation =
-        \\Cosine trigonometric function on a floating point number. Uses a dedicated hardware instruction when available.
+        \\Cosine trigometric function on a floating point number. Uses a dedicated hardware instruction when available.
         \\
-        \\Supports [Floats](https://ziglang.org/documentation/master/#Floats) and [Vectors](https://ziglang.org/documentation/master/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
+        \\Supports [Floats](https://ziglang.org/documentation/0.8.1/#Floats) and [Vectors](https://ziglang.org/documentation/0.8.1/#Vectors) of floats, with the caveat that
+        \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
         ,
         .arguments = &.{
             "value: anytype",
@@ -1473,7 +1574,8 @@ pub const builtins = [_]Builtin{
         .documentation =
         \\Base-e exponential function on a floating point number. Uses a dedicated hardware instruction when available.
         \\
-        \\Supports [Floats](https://ziglang.org/documentation/master/#Floats) and [Vectors](https://ziglang.org/documentation/master/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
+        \\Supports [Floats](https://ziglang.org/documentation/0.8.1/#Floats) and [Vectors](https://ziglang.org/documentation/0.8.1/#Vectors) of floats, with the caveat that
+        \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
         ,
         .arguments = &.{
             "value: anytype",
@@ -1486,7 +1588,8 @@ pub const builtins = [_]Builtin{
         .documentation =
         \\Base-2 exponential function on a floating point number. Uses a dedicated hardware instruction when available.
         \\
-        \\Supports [Floats](https://ziglang.org/documentation/master/#Floats) and [Vectors](https://ziglang.org/documentation/master/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
+        \\Supports [Floats](https://ziglang.org/documentation/0.8.1/#Floats) and [Vectors](https://ziglang.org/documentation/0.8.1/#Vectors) of floats, with the caveat that
+        \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
         ,
         .arguments = &.{
             "value: anytype",
@@ -1499,7 +1602,8 @@ pub const builtins = [_]Builtin{
         .documentation =
         \\Returns the natural logarithm of a floating point number. Uses a dedicated hardware instruction when available.
         \\
-        \\Supports [Floats](https://ziglang.org/documentation/master/#Floats) and [Vectors](https://ziglang.org/documentation/master/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
+        \\Supports [Floats](https://ziglang.org/documentation/0.8.1/#Floats) and [Vectors](https://ziglang.org/documentation/0.8.1/#Vectors) of floats, with the caveat that
+        \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
         ,
         .arguments = &.{
             "value: anytype",
@@ -1512,7 +1616,8 @@ pub const builtins = [_]Builtin{
         .documentation =
         \\Returns the logarithm to the base 2 of a floating point number. Uses a dedicated hardware instruction when available.
         \\
-        \\Supports [Floats](https://ziglang.org/documentation/master/#Floats) and [Vectors](https://ziglang.org/documentation/master/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
+        \\Supports [Floats](https://ziglang.org/documentation/0.8.1/#Floats) and [Vectors](https://ziglang.org/documentation/0.8.1/#Vectors) of floats, with the caveat that
+        \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
         ,
         .arguments = &.{
             "value: anytype",
@@ -1525,7 +1630,8 @@ pub const builtins = [_]Builtin{
         .documentation =
         \\Returns the logarithm to the base 10 of a floating point number. Uses a dedicated hardware instruction when available.
         \\
-        \\Supports [Floats](https://ziglang.org/documentation/master/#Floats) and [Vectors](https://ziglang.org/documentation/master/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
+        \\Supports [Floats](https://ziglang.org/documentation/0.8.1/#Floats) and [Vectors](https://ziglang.org/documentation/0.8.1/#Vectors) of floats, with the caveat that
+        \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
         ,
         .arguments = &.{
             "value: anytype",
@@ -1538,7 +1644,8 @@ pub const builtins = [_]Builtin{
         .documentation =
         \\Returns the absolute value of a floating point number. Uses a dedicated hardware instruction when available.
         \\
-        \\Supports [Floats](https://ziglang.org/documentation/master/#Floats) and [Vectors](https://ziglang.org/documentation/master/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
+        \\Supports [Floats](https://ziglang.org/documentation/0.8.1/#Floats) and [Vectors](https://ziglang.org/documentation/0.8.1/#Vectors) of floats, with the caveat that
+        \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
         ,
         .arguments = &.{
             "value: anytype",
@@ -1551,7 +1658,8 @@ pub const builtins = [_]Builtin{
         .documentation =
         \\Returns the largest integral value not greater than the given floating point number. Uses a dedicated hardware instruction when available.
         \\
-        \\Supports [Floats](https://ziglang.org/documentation/master/#Floats) and [Vectors](https://ziglang.org/documentation/master/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
+        \\Supports [Floats](https://ziglang.org/documentation/0.8.1/#Floats) and [Vectors](https://ziglang.org/documentation/0.8.1/#Vectors) of floats, with the caveat that
+        \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
         ,
         .arguments = &.{
             "value: anytype",
@@ -1564,7 +1672,8 @@ pub const builtins = [_]Builtin{
         .documentation =
         \\Returns the largest integral value not less than the given floating point number. Uses a dedicated hardware instruction when available.
         \\
-        \\Supports [Floats](https://ziglang.org/documentation/master/#Floats) and [Vectors](https://ziglang.org/documentation/master/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
+        \\Supports [Floats](https://ziglang.org/documentation/0.8.1/#Floats) and [Vectors](https://ziglang.org/documentation/0.8.1/#Vectors) of floats, with the caveat that
+        \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
         ,
         .arguments = &.{
             "value: anytype",
@@ -1577,7 +1686,8 @@ pub const builtins = [_]Builtin{
         .documentation =
         \\Rounds the given floating point number to an integer, towards zero. Uses a dedicated hardware instruction when available.
         \\
-        \\Supports [Floats](https://ziglang.org/documentation/master/#Floats) and [Vectors](https://ziglang.org/documentation/master/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
+        \\Supports [Floats](https://ziglang.org/documentation/0.8.1/#Floats) and [Vectors](https://ziglang.org/documentation/0.8.1/#Vectors) of floats, with the caveat that
+        \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
         ,
         .arguments = &.{
             "value: anytype",
@@ -1590,7 +1700,8 @@ pub const builtins = [_]Builtin{
         .documentation =
         \\Rounds the given floating point number to an integer, away from zero. Uses a dedicated hardware instruction when available.
         \\
-        \\Supports [Floats](https://ziglang.org/documentation/master/#Floats) and [Vectors](https://ziglang.org/documentation/master/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
+        \\Supports [Floats](https://ziglang.org/documentation/0.8.1/#Floats) and [Vectors](https://ziglang.org/documentation/0.8.1/#Vectors) of floats, with the caveat that
+        \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
         ,
         .arguments = &.{
             "value: anytype",
@@ -1612,12 +1723,12 @@ pub const builtins = [_]Builtin{
     },
     .{
         .name = "@tagName",
-        .signature = "@tagName(value: anytype) [:0]const u8",
+        .signature = "@tagName(value: anytype) []const u8",
         .snippet = "@tagName(${1:value: anytype})",
         .documentation =
-        \\Converts an enum value or union value to a string literal representing the name.
+        \\Converts an enum value or union value to a slice of bytes representing the name.
         \\
-        \\If the enum is non-exhaustive and the tag value does not map to a name, it invokes safety-checked [Undefined Behavior](https://ziglang.org/documentation/master/#Undefined-Behavior).
+        \\If the enum is non-exhaustive and the tag value does not map to a name, it invokes safety-checked [Undefined Behavior](https://ziglang.org/documentation/0.8.1/#Undefined-Behavior).
         ,
         .arguments = &.{
             "value: anytype",
@@ -1628,13 +1739,27 @@ pub const builtins = [_]Builtin{
         .signature = "@This() type",
         .snippet = "@This()",
         .documentation =
-        \\Returns the innermost struct, enum, or union that this function call is inside. This can be useful for an anonymous struct that needs to refer to itself:

{#code_begin|test|this_innermost#} const std = @import("std"); const expect = std.testing.expect; test "@This()" { var items = [_]i32{ 1, 2, 3, 4 }; const list = List(i32){ .items = items[0..] }; try expect(list.length() == 4); } fn List(comptime T: type) type { return struct { const Self = @This(); items: []T, fn length(self: Self) usize { return self.items.len; } }; }`
-        \\      
+        \\Returns the innermost struct, enum, or union that this function call is inside. This can be useful for an anonymous struct that needs to refer to itself:
         \\
-        \\
-        \\      When `@This()` is used at file scope, it returns a reference to the
-        \\      struct that corresponds to the current file.
-        \\      
+        \\```zig
+        \\const std = @import("std");
+        \\const expect = std.testing.expect;
+        \\test "@This()" {
+        \\    var items = [_]i32{ 1, 2, 3, 4 };
+        \\    const list = List(i32){ .items = items[0..] };
+        \\    try expect(list.length() == 4);
+        \\}
+        \\fn List(comptime T: type) type {
+        \\    return struct {
+        \\        const Self = @This();
+        \\        items: []T,
+        \\        fn length(self: Self) usize {
+        \\            return self.items.len;
+        \\        }
+        \\    };
+        \\}
+        \\```
+        \\When `@This()` is used at file scope, it returns a reference to the struct that corresponds to the current file.
         ,
         .arguments = &.{},
     },
@@ -1645,29 +1770,25 @@ pub const builtins = [_]Builtin{
         .documentation =
         \\This function truncates bits from an integer type, resulting in a smaller or same-sized integer type.
         \\
-        \\The following produces safety-checked [Undefined Behavior](https://ziglang.org/documentation/master/#Undefined-Behavior):
+        \\The following produces safety-checked [Undefined Behavior](https://ziglang.org/documentation/0.8.1/#Undefined-Behavior):
         \\
         \\```zig
         \\test "integer cast panic" {
         \\    var a: u16 = 0xabcd;
         \\    var b: u8 = @intCast(u8, a);
-        \\    _ = b;
         \\}
         \\```
-        \\
         \\However this is well defined and working code:
         \\
         \\```zig
         \\const std = @import("std");
         \\const expect = std.testing.expect;
-        \\
         \\test "integer truncation" {
         \\    var a: u16 = 0xabcd;
         \\    var b: u8 = @truncate(u8, a);
         \\    try expect(b == 0xcd);
         \\}
         \\```
-        \\
         \\This function always truncates the significant bits of the integer, regardless of endianness on the target platform.
         ,
         .arguments = &.{
@@ -1680,36 +1801,37 @@ pub const builtins = [_]Builtin{
         .signature = "@Type(comptime info: std.builtin.TypeInfo) type",
         .snippet = "@Type(${1:comptime info: std.builtin.TypeInfo})",
         .documentation =
-        \\This function is the inverse of [@typeInfo](https://ziglang.org/documentation/master/#typeInfo). It reifies type information into a `type`.
+        \\This function is the inverse of [@typeInfo](https://ziglang.org/documentation/0.8.1/#typeInfo). It reifies type information into a `type`.
         \\
         \\It is available for the following types:
-        \\  - `type`
-        \\  - `noreturn`
-        \\  - `void`
-        \\  - `bool`
-        \\  - [Integers](https://ziglang.org/documentation/master/#Integers) - The maximum bit count for an integer type is `65535`.
-        \\  - [Floats](https://ziglang.org/documentation/master/#Floats)
-        \\  - [Pointers](https://ziglang.org/documentation/master/#Pointers)
-        \\  - `comptime_int`
-        \\  - `comptime_float`
-        \\  - `@TypeOf(undefined)`
-        \\  - `@TypeOf(null)`
-        \\  - [Arrays](https://ziglang.org/documentation/master/#Arrays)
-        \\  - [Optionals](https://ziglang.org/documentation/master/#Optionals)
-        \\  - [Error Set Type](https://ziglang.org/documentation/master/#Error-Set-Type)
-        \\  - [Error Union Type](https://ziglang.org/documentation/master/#Error-Union-Type)
-        \\  - [Vectors](https://ziglang.org/documentation/master/#Vectors)
-        \\  - [opaque](https://ziglang.org/documentation/master/#opaque)
-        \\  - [@Frame](https://ziglang.org/documentation/master/#Frame)
-        \\  - `anyframe`
-        \\  - [struct](https://ziglang.org/documentation/master/#struct)
-        \\  - [enum](https://ziglang.org/documentation/master/#enum)
-        \\  - [Enum Literals](https://ziglang.org/documentation/master/#Enum-Literals)
-        \\  - [union](https://ziglang.org/documentation/master/#union)
         \\
+        \\ - `type`
+        \\ - `noreturn`
+        \\ - `void`
+        \\ - `bool`
+        \\ - [Integers](https://ziglang.org/documentation/0.8.1/#Integers) - The maximum bit count for an integer type is `65535`.
+        \\ - [Floats](https://ziglang.org/documentation/0.8.1/#Floats)
+        \\ - [Pointers](https://ziglang.org/documentation/0.8.1/#Pointers)
+        \\ - `comptime_int`
+        \\ - `comptime_float`
+        \\ - `@TypeOf(undefined)`
+        \\ - `@TypeOf(null)`
+        \\ - [Arrays](https://ziglang.org/documentation/0.8.1/#Arrays)
+        \\ - [Optionals](https://ziglang.org/documentation/0.8.1/#Optionals)
+        \\ - [Error Set Type](https://ziglang.org/documentation/0.8.1/#Error-Set-Type)
+        \\ - [Error Union Type](https://ziglang.org/documentation/0.8.1/#Error-Union-Type)
+        \\ - [Vectors](https://ziglang.org/documentation/0.8.1/#Vectors)
+        \\ - [opaque](https://ziglang.org/documentation/0.8.1/#opaque)
+        \\ - [@Frame](https://ziglang.org/documentation/0.8.1/#Frame)
+        \\ - `anyframe`
+        \\ - [struct](https://ziglang.org/documentation/0.8.1/#struct)
+        \\ - [enum](https://ziglang.org/documentation/0.8.1/#enum)
+        \\ - [Enum Literals](https://ziglang.org/documentation/0.8.1/#Enum-Literals)
+        \\ - [union](https://ziglang.org/documentation/0.8.1/#union)
         \\For these types, `@Type` is not available:
-        \\  - [Functions](https://ziglang.org/documentation/master/#Functions)
-        \\  - BoundFn
+        \\
+        \\ - [Functions](https://ziglang.org/documentation/0.8.1/#Functions)
+        \\ - BoundFn
         ,
         .arguments = &.{
             "comptime info: std.builtin.TypeInfo",
@@ -1722,7 +1844,7 @@ pub const builtins = [_]Builtin{
         .documentation =
         \\Provides type reflection.
         \\
-        \\For [structs](https://ziglang.org/documentation/master/#struct), [unions](https://ziglang.org/documentation/master/#union), [enums](https://ziglang.org/documentation/master/#enum), and [error sets](https://ziglang.org/documentation/master/#Error-Set-Type), the fields are guaranteed to be in the same order as declared. For declarations, the order is unspecified.
+        \\For [structs](https://ziglang.org/documentation/0.8.1/#struct), [unions](https://ziglang.org/documentation/0.8.1/#union), [enums](https://ziglang.org/documentation/0.8.1/#enum), and [error sets](https://ziglang.org/documentation/0.8.1/#Error-Set-Type), the fields are guaranteed to be in the same order as declared. For declarations, the order is unspecified.
         ,
         .arguments = &.{
             "comptime T: type",
@@ -1730,7 +1852,7 @@ pub const builtins = [_]Builtin{
     },
     .{
         .name = "@typeName",
-        .signature = "@typeName(T: type) *const [N:0]u8",
+        .signature = "@typeName(T: type) [N]u8",
         .snippet = "@typeName(${1:T: type})",
         .documentation =
         \\This function returns the string representation of a type, as an array. It is equivalent to a string literal of the type name.
@@ -1744,9 +1866,25 @@ pub const builtins = [_]Builtin{
         .signature = "@TypeOf(...) type",
         .snippet = "@TypeOf(${1:...})",
         .documentation =
-        \\`@TypeOf` is a special builtin function that takes any (nonzero) number of expressions as parameters and returns the type of the result, using [Peer Type Resolution](https://ziglang.org/documentation/master/#Peer-Type-Resolution).
+        \\`@TypeOf` is a special builtin function that takes any (nonzero) number of expressions as parameters and returns the type of the result, using [Peer Type Resolution](https://ziglang.org/documentation/0.8.1/#Peer-Type-Resolution).
         \\
-        \\The expressions are evaluated, however they are guaranteed to have no *runtime* side-effects:

{#code_begin|test|no_runtime_side_effects#} const std = @import("std"); const expect = std.testing.expect; test "no runtime side effects" { var data: i32 = 0; const T = @TypeOf(foo(i32, &data)); comptime try expect(T == i32); try expect(data == 0); } fn foo(comptime T: type, ptr: *T) T { ptr.* += 1; return ptr.*; }`
+        \\The expressions are evaluated, however they are guaranteed to have no
+        \\**runtime** side-effects:
+        \\
+        \\```zig
+        \\const std = @import("std");
+        \\const expect = std.testing.expect;
+        \\test "no runtime side effects" {
+        \\    var data: i32 = 0;
+        \\    const T = @TypeOf(foo(i32, &data));
+        \\    comptime try expect(T == i32);
+        \\    try expect(data == 0);
+        \\}
+        \\fn foo(comptime T: type, ptr: *T) T {
+        \\    ptr.* += 1;
+        \\    return ptr.*;
+        \\}
+        \\```
         ,
         .arguments = &.{
             "...",
@@ -1757,9 +1895,9 @@ pub const builtins = [_]Builtin{
         .signature = "@unionInit(comptime Union: type, comptime active_field_name: []const u8, init_expr) Union",
         .snippet = "@unionInit(${1:comptime Union: type}, ${2:comptime active_field_name: []const u8}, ${3:init_expr})",
         .documentation =
-        \\This is the same thing as [union](https://ziglang.org/documentation/master/#union) initialization syntax, except that the field name is a [comptime](https://ziglang.org/documentation/master/#comptime)-known value rather than an identifier token.
+        \\This is the same thing as [union](https://ziglang.org/documentation/0.8.1/#union) initialization syntax, except that the field name is a [comptime](https://ziglang.org/documentation/0.8.1/#comptime)-known value rather than an identifier token.
         \\
-        \\`@unionInit` forwards its [result location](https://ziglang.org/documentation/master/#Result-Location-Semantics) to `init_expr`.
+        \\`@unionInit` forwards its [result location](https://ziglang.org/documentation/0.8.1/#Result-Location-Semantics) to `init_expr`.
         ,
         .arguments = &.{
             "comptime Union: type",
@@ -1768,3 +1906,5 @@ pub const builtins = [_]Builtin{
         },
     },
 };
+
+// DO NOT EDIT
diff --git a/src/data/0.9.0.zig b/src/data/0.9.0.zig
index 161d4e6..18b0c0c 100644
--- a/src/data/0.9.0.zig
+++ b/src/data/0.9.0.zig
@@ -1,3 +1,8 @@
+//! DO NOT EDIT
+//! If you want to update this file run:
+//! `zig build gen -- --generate-version-data 0.9.0` (requires an internet connection)
+//! GENERATED BY src/config_gen/config_gen.zig
+
 const Builtin = struct {
     name: []const u8,
     signature: []const u8,
@@ -48,8 +53,7 @@ pub const builtins = [_]Builtin{
         \\    assert(*u32 == *align(@alignOf(u32)) u32);
         \\}
         \\```
-        \\
-        \\The result is a target-specific compile time constant. It is guaranteed to be less than or equal to [@sizeOf(T)](https://ziglang.org/documentation/0.9.0/#@sizeOf).
+        \\The result is a target-specific compile time constant. It is guaranteed to be less than or equal to [@sizeOf(T)](https://ziglang.org/documentation/0.9.0/#sizeOf).
         ,
         .arguments = &.{
             "comptime T: type",
@@ -70,19 +74,38 @@ pub const builtins = [_]Builtin{
     .{
         .name = "@asyncCall",
         .signature = "@asyncCall(frame_buffer: []align(@alignOf(@Frame(anyAsyncFunction))) u8, result_ptr, function_ptr, args: anytype) anyframe->T",
-        .snippet = "@asyncCall(${1:frame_buffer: []align(@alignOf(@Frame(anyAsyncFunction))) u8}, ${2:result_ptr}, ${3:function_ptr}, ${4:args: anytype})",
+        .snippet = "@asyncCall(${1:frame_buffer: []align(@alignOf(@Frame(anyAsyncFunction)})",
         .documentation =
         \\`@asyncCall` performs an `async` call on a function pointer, which may or may not be an [async function](https://ziglang.org/documentation/0.9.0/#Async-Functions).
         \\
         \\The provided `frame_buffer` must be large enough to fit the entire function frame. This size can be determined with [@frameSize](https://ziglang.org/documentation/0.9.0/#frameSize). To provide a too-small buffer invokes safety-checked [Undefined Behavior](https://ziglang.org/documentation/0.9.0/#Undefined-Behavior).
         \\
-        \\`result_ptr` is optional ([null](https://ziglang.org/documentation/0.9.0/#null) may be provided). If provided, the function call will write its result directly to the result pointer, which will be available to read after [await](https://ziglang.org/documentation/0.9.0/#Async-and-Await) completes. Any result location provided to `await` will copy the result from `result_ptr`.

{#code_begin|test|async_struct_field_fn_pointer#} const std = @import("std"); const expect = std.testing.expect; test "async fn pointer in a struct field" { var data: i32 = 1; const Foo = struct { bar: fn (*i32) callconv(.Async) void, }; var foo = Foo{ .bar = func }; var bytes: [64]u8 align(@alignOf(@Frame(func))) = undefined; const f = @asyncCall(&bytes, {}, foo.bar, .{&data}); try expect(data == 2); resume f; try expect(data == 4); } fn func(y: *i32) void { defer y.* += 2; y.* += 1; suspend {} }`
+        \\`result_ptr` is optional ([null](https://ziglang.org/documentation/0.9.0/#null) may be provided). If provided, the function call will write its result directly to the result pointer, which will be available to read after [await](https://ziglang.org/documentation/0.9.0/#Async-and-Await) completes. Any result location provided to `await` will copy the result from `result_ptr`.
+        \\
+        \\```zig
+        \\const std = @import("std");
+        \\const expect = std.testing.expect;
+        \\test "async fn pointer in a struct field" {
+        \\    var data: i32 = 1;
+        \\    const Foo = struct {
+        \\        bar: fn (*i32) callconv(.Async) void,
+        \\    };
+        \\    var foo = Foo{ .bar = func };
+        \\    var bytes: [64]u8 align(@alignOf(@Frame(func))) = undefined;
+        \\    const f = @asyncCall(&bytes, {}, foo.bar, .{&data});
+        \\    try expect(data == 2);
+        \\    resume f;
+        \\    try expect(data == 4);
+        \\}
+        \\fn func(y: *i32) void {
+        \\    defer y.* += 2;
+        \\    y.* += 1;
+        \\    suspend {}
+        \\}
+        \\```
         ,
         .arguments = &.{
-            "frame_buffer: []align(@alignOf(@Frame(anyAsyncFunction))) u8",
-            "result_ptr",
-            "function_ptr",
-            "args: anytype",
+            "frame_buffer: []align(@alignOf(@Frame(anyAsyncFunction)",
         },
     },
     .{
@@ -110,15 +133,16 @@ pub const builtins = [_]Builtin{
         \\`T` must be a pointer, a `bool`, a float, an integer or an enum.
         \\
         \\Supported operations:
-        \\  - `.Xchg` - stores the operand unmodified. Supports enums, integers and floats.
-        \\  - `.Add` - for integers, twos complement wraparound addition. Also supports [Floats](https://ziglang.org/documentation/0.9.0/#Floats).
-        \\  - `.Sub` - for integers, twos complement wraparound subtraction. Also supports [Floats](https://ziglang.org/documentation/0.9.0/#Floats).
-        \\  - `.And` - bitwise and
-        \\  - `.Nand` - bitwise nand
-        \\  - `.Or` - bitwise or
-        \\  - `.Xor` - bitwise xor
-        \\  - `.Max` - stores the operand if it is larger. Supports integers and floats.
-        \\  - `.Min` - stores the operand if it is smaller. Supports integers and floats.
+        \\
+        \\ - `.Xchg` - stores the operand unmodified. Supports enums, integers and floats.
+        \\ - `.Add` - for integers, twos complement wraparound addition. Also supports [Floats](https://ziglang.org/documentation/0.9.0/#Floats).
+        \\ - `.Sub` - for integers, twos complement wraparound subtraction. Also supports [Floats](https://ziglang.org/documentation/0.9.0/#Floats).
+        \\ - `.And` - bitwise and
+        \\ - `.Nand` - bitwise nand
+        \\ - `.Or` - bitwise or
+        \\ - `.Xor` - bitwise xor
+        \\ - `.Max` - stores the operand if it is larger. Supports integers and floats.
+        \\ - `.Min` - stores the operand if it is smaller. Supports integers and floats.
         ,
         .arguments = &.{
             "comptime T: type",
@@ -156,9 +180,9 @@ pub const builtins = [_]Builtin{
         \\Asserts that `@typeInfo(DestType) != .Pointer`. Use `@ptrCast` or `@intToPtr` if you need this.
         \\
         \\Can be used for these things for example:
-        \\  - Convert `f32` to `u32` bits
-        \\  - Convert `i32` to `u32` preserving twos complement
         \\
+        \\ - Convert `f32` to `u32` bits
+        \\ - Convert `i32` to `u32` preserving twos complement
         \\Works at compile-time if `value` is known at compile time. It's a compile error to bitcast a struct to a scalar type of the same size since structs have undefined layout. However if the struct is packed then it works.
         ,
         .arguments = &.{
@@ -288,17 +312,48 @@ pub const builtins = [_]Builtin{
         \\
         \\```zig
         \\const expect = @import("std").testing.expect;
-        \\
         \\test "noinline function call" {
         \\    try expect(@call(.{}, add, .{3, 9}) == 12);
         \\}
-        \\
         \\fn add(a: i32, b: i32) i32 {
         \\    return a + b;
         \\}
         \\```
+        \\`@call` allows more flexibility than normal function call syntax does. The `CallOptions` struct is reproduced here:
         \\
-        \\`@call` allows more flexibility than normal function call syntax does. The `CallOptions` struct is reproduced here:

{#syntax_block|zig|builtin.CallOptions struct#} pub const CallOptions = struct { modifier: Modifier = .auto, /// Only valid when `Modifier` is `Modifier.async_kw`. stack: ?[]align(std.Target.stack_align) u8 = null, pub const Modifier = enum { /// Equivalent to function call syntax. auto, /// Equivalent to async keyword used with function call syntax. async_kw, /// Prevents tail call optimization. This guarantees that the return /// address will point to the callsite, as opposed to the callsite's /// callsite. If the call is otherwise required to be tail-called /// or inlined, a compile error is emitted instead. never_tail, /// Guarantees that the call will not be inlined. If the call is /// otherwise required to be inlined, a compile error is emitted instead. never_inline, /// Asserts that the function call will not suspend. This allows a /// non-async function to call an async function. no_async, /// Guarantees that the call will be generated with tail call optimization. /// If this is not possible, a compile error is emitted instead. always_tail, /// Guarantees that the call will inlined at the callsite. /// If this is not possible, a compile error is emitted instead. always_inline, /// Evaluates the call at compile-time. If the call cannot be completed at /// compile-time, a compile error is emitted instead. compile_time, }; }; {#end_syntax_block#} + \\```zig + \\pub const CallOptions = struct { + \\ modifier: Modifier = .auto, + \\ /// Only valid when `Modifier` is `Modifier.async_kw`. + \\ stack: ?[]align(std.Target.stack_align) u8 = null, + \\ pub const Modifier = enum { + \\ /// Equivalent to function call syntax. + \\ auto, + \\ /// Equivalent to async keyword used with function call syntax. + \\ async_kw, + \\ /// Prevents tail call optimization. This guarantees that the return + \\ /// address will point to the callsite, as opposed to the callsite's + \\ /// callsite. If the call is otherwise required to be tail-called + \\ /// or inlined, a compile error is emitted instead. + \\ never_tail, + \\ /// Guarantees that the call will not be inlined. If the call is + \\ /// otherwise required to be inlined, a compile error is emitted instead. + \\ never_inline, + \\ /// Asserts that the function call will not suspend. This allows a + \\ /// non-async function to call an async function. + \\ no_async, + \\ /// Guarantees that the call will be generated with tail call optimization. + \\ /// If this is not possible, a compile error is emitted instead. + \\ always_tail, + \\ /// Guarantees that the call will inlined at the callsite. + \\ /// If this is not possible, a compile error is emitted instead. + \\ always_inline, + \\ /// Evaluates the call at compile-time. If the call cannot be completed at + \\ /// compile-time, a compile error is emitted instead. + \\ compile_time, + \\ }; + \\}; + \\``` , .arguments = &.{ "options: std.builtin.CallOptions", @@ -313,15 +368,14 @@ pub const builtins = [_]Builtin{ .documentation = \\This function can only occur inside `@cImport`. \\ - \\This appends `#define $name $value` to the `@cImport` temporary buffer. + \\This appends + \\`#define $name $value`to the `@cImport` temporary buffer. \\ - \\To define without a value, like this:`#define _GNU_SOURCE` + \\To define without a value, like this: \\ - \\Use the void value, like this: + \\`#define _GNU_SOURCE`Use the void value, like this: \\ - \\```zig - \\@cDefine("_GNU_SOURCE", {}) - \\``` + \\`@cDefine("_GNU_SOURCE", {})` , .arguments = &.{ "comptime name: []u8", @@ -340,8 +394,9 @@ pub const builtins = [_]Builtin{ \\Usually you should only have one `@cImport` in your entire application, because it saves the compiler from invoking clang multiple times, and prevents inline functions from being duplicated. \\ \\Reasons for having multiple `@cImport` expressions would be: - \\ - To avoid a symbol collision, for example if foo.h and bar.h both `#define CONNECTION_COUNT` - \\ - To analyze the C code with different preprocessor defines + \\ + \\ - To avoid a symbol collision, for example if foo.h and bar.h both + \\`#define CONNECTION_COUNT` - To analyze the C code with different preprocessor defines , .arguments = &.{ "expression", @@ -354,7 +409,8 @@ pub const builtins = [_]Builtin{ .documentation = \\This function can only occur inside `@cImport`. \\ - \\This appends `#include <$path>\n` to the `c_import` temporary buffer. + \\This appends + \\`#include <$path>\n`to the `c_import` temporary buffer. , .arguments = &.{ "comptime path: []u8", @@ -398,7 +454,6 @@ pub const builtins = [_]Builtin{ \\ } \\} \\``` - \\ \\If you are using cmpxchg in a loop, [@cmpxchgWeak](https://ziglang.org/documentation/0.9.0/#cmpxchgWeak) is the better choice, because it can be implemented more efficiently in machine instructions. \\ \\`T` must be a pointer, a `bool`, a float, an integer or an enum. @@ -419,8 +474,19 @@ pub const builtins = [_]Builtin{ .signature = "@cmpxchgWeak(comptime T: type, ptr: *T, expected_value: T, new_value: T, success_order: AtomicOrder, fail_order: AtomicOrder) ?T", .snippet = "@cmpxchgWeak(${1:comptime T: type}, ${2:ptr: *T}, ${3:expected_value: T}, ${4:new_value: T}, ${5:success_order: AtomicOrder}, ${6:fail_order: AtomicOrder})", .documentation = - \\This function performs a weak atomic compare exchange operation. It's the equivalent of this code, except atomic:

{#syntax_block|zig|cmpxchgWeakButNotAtomic#} fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_value: T) ?T { const old_value = ptr.*; if (old_value == expected_value and usuallyTrueButSometimesFalse()) { ptr.* = new_value; return null; } else { return old_value; } } {#end_syntax_block#} + \\This function performs a weak atomic compare exchange operation. It's the equivalent of this code, except atomic: \\ + \\```zig + \\fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_value: T) ?T { + \\ const old_value = ptr.*; + \\ if (old_value == expected_value and usuallyTrueButSometimesFalse()) { + \\ ptr.* = new_value; + \\ return null; + \\ } else { + \\ return old_value; + \\ } + \\} + \\``` \\If you are using cmpxchg in a loop, the sporadic failure will be no problem, and `cmpxchgWeak` is the better choice, because it can be implemented more efficiently in machine instructions. However if you need a stronger guarantee, use [@cmpxchgStrong](https://ziglang.org/documentation/0.9.0/#cmpxchgStrong). \\ \\`T` must be a pointer, a `bool`, a float, an integer or an enum. @@ -462,24 +528,32 @@ pub const builtins = [_]Builtin{ \\ \\```zig \\const print = @import("std").debug.print; - \\ \\const num1 = blk: { \\ var val1: i32 = 99; \\ @compileLog("comptime val1 = ", val1); \\ val1 = val1 + 1; \\ break :blk val1; \\}; - \\ \\test "main" { \\ @compileLog("comptime in main"); - \\ \\ print("Runtime in main, num1 = {}.\n", .{num1}); \\} \\``` - \\ \\will output: \\ - \\If all `@compileLog` calls are removed or not encountered by analysis, the program compiles successfully and the generated executable prints:

{#code_begin|test|without_compileLog#} const print = @import("std").debug.print; const num1 = blk: { var val1: i32 = 99; val1 = val1 + 1; break :blk val1; }; test "main" { print("Runtime in main, num1 = {}.\n", .{num1}); }`
+        \\If all `@compileLog` calls are removed or not encountered by analysis, the program compiles successfully and the generated executable prints:
+        \\
+        \\```zig
+        \\const print = @import("std").debug.print;
+        \\const num1 = blk: {
+        \\    var val1: i32 = 99;
+        \\    val1 = val1 + 1;
+        \\    break :blk val1;
+        \\};
+        \\test "main" {
+        \\    print("Runtime in main, num1 = {}.\n", .{num1});
+        \\}
+        \\```
         ,
         .arguments = &.{
             "args: ...",
@@ -512,7 +586,8 @@ pub const builtins = [_]Builtin{
         .documentation =
         \\This function can only occur inside `@cImport`.
         \\
-        \\This appends `#undef $name` to the `@cImport` temporary buffer.
+        \\This appends
+        \\`#undef $name`to the `@cImport` temporary buffer.
         ,
         .arguments = &.{
             "comptime name: []u8",
@@ -524,9 +599,9 @@ pub const builtins = [_]Builtin{
         .snippet = "@divExact(${1:numerator: T}, ${2:denominator: T})",
         .documentation =
         \\Exact division. Caller guarantees `denominator != 0` and `@divTrunc(numerator, denominator) * denominator == numerator`.
-        \\  - `@divExact(6, 3) == 2`
-        \\  - `@divExact(a, b) * b == a`
         \\
+        \\ - `@divExact(6, 3) == 2`
+        \\ - `@divExact(a, b) * b == a`
         \\For a function that returns a possible error code, use `@import("std").math.divExact`.
         ,
         .arguments = &.{
@@ -540,9 +615,9 @@ pub const builtins = [_]Builtin{
         .snippet = "@divFloor(${1:numerator: T}, ${2:denominator: T})",
         .documentation =
         \\Floored division. Rounds toward negative infinity. For unsigned integers it is the same as `numerator / denominator`. Caller guarantees `denominator != 0` and `!(@typeInfo(T) == .Int and T.is_signed and numerator == std.math.minInt(T) and denominator == -1)`.
-        \\  - `@divFloor(-5, 3) == -2`
-        \\  - `(@divFloor(a, b) * b) + @mod(a, b) == a`
         \\
+        \\ - `@divFloor(-5, 3) == -2`
+        \\ - `(@divFloor(a, b) * b) + @mod(a, b) == a`
         \\For a function that returns a possible error code, use `@import("std").math.divFloor`.
         ,
         .arguments = &.{
@@ -556,9 +631,9 @@ pub const builtins = [_]Builtin{
         .snippet = "@divTrunc(${1:numerator: T}, ${2:denominator: T})",
         .documentation =
         \\Truncated division. Rounds toward zero. For unsigned integers it is the same as `numerator / denominator`. Caller guarantees `denominator != 0` and `!(@typeInfo(T) == .Int and T.is_signed and numerator == std.math.minInt(T) and denominator == -1)`.
-        \\  - `@divTrunc(-5, 3) == -1`
-        \\  - `(@divTrunc(a, b) * b) + @rem(a, b) == a`
         \\
+        \\ - `@divTrunc(-5, 3) == -1`
+        \\ - `(@divTrunc(a, b) * b) + @rem(a, b) == a`
         \\For a function that returns a possible error code, use `@import("std").math.divTrunc`.
         ,
         .arguments = &.{
@@ -620,10 +695,10 @@ pub const builtins = [_]Builtin{
         .snippet = "@errorToInt(${1:err: anytype})",
         .documentation =
         \\Supports the following types:
-        \\  - [The Global Error Set](https://ziglang.org/documentation/0.9.0/#The-Global-Error-Set)
-        \\  - [Error Set Type](https://ziglang.org/documentation/0.9.0/#Error-Set-Type)
-        \\  - [Error Union Type](https://ziglang.org/documentation/0.9.0/#Error-Union-Type)
         \\
+        \\ - [The Global Error Set](https://ziglang.org/documentation/0.9.0/#The-Global-Error-Set)
+        \\ - [Error Set Type](https://ziglang.org/documentation/0.9.0/#Error-Set-Type)
+        \\ - [Error Union Type](https://ziglang.org/documentation/0.9.0/#Error-Union-Type)
         \\Converts an error to the integer representation of an error.
         \\
         \\It is generally recommended to avoid this cast, as the integer representation of an error is not stable across source code changes.
@@ -651,37 +726,28 @@ pub const builtins = [_]Builtin{
         .documentation =
         \\Creates a symbol in the output object file.
         \\
-        \\`declaration` must be one of two things:
-        \\  - An identifier (`x`) identifying a [function](https://ziglang.org/documentation/0.9.0/#Functions) or a [variable](https://ziglang.org/documentation/0.9.0/#Container-Level-Variables).
-        \\  - Field access (`x.y`) looking up a [function](https://ziglang.org/documentation/0.9.0/#Functions) or a [variable](https://ziglang.org/documentation/0.9.0/#Container-Level-Variables).
+        \\`declaration`must be one of two things:
         \\
-        \\This builtin can be called from a [comptime](https://ziglang.org/documentation/0.9.0/#comptime) block to conditionally export symbols. When `declaration` is a function with the C calling convention and `options.linkage` is `Strong`, this is equivalent to the `export` keyword used on a function:
+        \\ - An identifier (`x`) identifying a [function](https://ziglang.org/documentation/0.9.0/#Functions) or a [variable](https://ziglang.org/documentation/0.9.0/#Container-Level-Variables).
+        \\ - Field access (`x.y`) looking up a [function](https://ziglang.org/documentation/0.9.0/#Functions) or a [variable](https://ziglang.org/documentation/0.9.0/#Container-Level-Variables).
+        \\This builtin can be called from a [comptime](https://ziglang.org/documentation/0.9.0/#comptime) block to conditionally export symbols. When
+        \\`declaration`is a function with the C calling convention and `options.linkage` is `Strong`, this is equivalent to the `export` keyword used on a function:
         \\
         \\```zig
         \\comptime {
         \\    @export(internalName, .{ .name = "foo", .linkage = .Strong });
         \\}
-        \\
         \\fn internalName() callconv(.C) void {}
         \\```
-        \\
         \\This is equivalent to:
         \\
-        \\```zig
-        \\export fn foo() void {}
-        \\```
-        \\
+        \\`export fn foo() void {}`
         \\Note that even when using `export`, `@"foo"` syntax can be used to choose any string for the symbol name:
         \\
-        \\```zig
-        \\export fn @"A function name that is a complete sentence."() void {}
-        \\```
-        \\
+        \\`export fn @"A function name that is a complete sentence."() void {}`
         \\When looking at the resulting object, you can see the symbol is used verbatim:
         \\
-        \\```zig
-        \\00000000000001f0 T A function name that is a complete sentence.
-        \\```
+        \\`00000000000001f0 T A function name that is a complete sentence.`
         ,
         .arguments = &.{
             "declaration",
@@ -718,7 +784,30 @@ pub const builtins = [_]Builtin{
         .signature = "@field(lhs: anytype, comptime field_name: []const u8) (field)",
         .snippet = "@field(${1:lhs: anytype}, ${2:comptime field_name: []const u8})",
         .documentation =
-        \\Performs field access by a compile-time string. Works on both fields and declarations.

{#code_begin|test|field_decl_access_by_string#} const std = @import("std"); const Point = struct { x: u32, y: u32, pub var z: u32 = 1; }; test "field access by string" { const expect = std.testing.expect; var p = Point{ .x = 0, .y = 0 }; @field(p, "x") = 4; @field(p, "y") = @field(p, "x") + 1; try expect(@field(p, "x") == 4); try expect(@field(p, "y") == 5); } test "decl access by string" { const expect = std.testing.expect; try expect(@field(Point, "z") == 1); @field(Point, "z") = 2; try expect(@field(Point, "z") == 2); }`
+        \\Performs field access by a compile-time string. Works on both fields and declarations.
+        \\
+        \\```zig
+        \\const std = @import("std");
+        \\const Point = struct {
+        \\    x: u32,
+        \\    y: u32,
+        \\    pub var z: u32 = 1;
+        \\};
+        \\test "field access by string" {
+        \\    const expect = std.testing.expect;
+        \\    var p = Point{ .x = 0, .y = 0 };
+        \\    @field(p, "x") = 4;
+        \\    @field(p, "y") = @field(p, "x") + 1;
+        \\    try expect(@field(p, "x") == 4);
+        \\    try expect(@field(p, "y") == 5);
+        \\}
+        \\test "decl access by string" {
+        \\    const expect = std.testing.expect;
+        \\    try expect(@field(Point, "z") == 1);
+        \\    @field(Point, "z") = 2;
+        \\    try expect(@field(Point, "z") == 2);
+        \\}
+        \\```
         ,
         .arguments = &.{
             "lhs: anytype",
@@ -727,7 +816,7 @@ pub const builtins = [_]Builtin{
     },
     .{
         .name = "@fieldParentPtr",
-        .signature = "@fieldParentPtr(comptime ParentType: type, comptime field_name: []const u8, field_ptr: *T) *ParentType",
+        .signature = "@fieldParentPtr(comptime ParentType: type, comptime field_name: []const u8,    field_ptr: *T) *ParentType",
         .snippet = "@fieldParentPtr(${1:comptime ParentType: type}, ${2:comptime field_name: []const u8}, ${3:field_ptr: *T})",
         .documentation =
         \\Given a pointer to a field, returns the base pointer of a struct.
@@ -782,7 +871,18 @@ pub const builtins = [_]Builtin{
         .documentation =
         \\This function returns the frame type of a function. This works for [Async Functions](https://ziglang.org/documentation/0.9.0/#Async-Functions) as well as any function without a specific calling convention.
         \\
-        \\This type is suitable to be used as the return type of [async](https://ziglang.org/documentation/0.9.0/#Async-and-Await) which allows one to, for example, heap-allocate an async function frame:

{#code_begin|test|heap_allocated_frame#} const std = @import("std"); test "heap allocated frame" { const frame = try std.heap.page_allocator.create(@Frame(func)); frame.* = async func(); } fn func() void { suspend {} }`
+        \\This type is suitable to be used as the return type of [async](https://ziglang.org/documentation/0.9.0/#Async-and-Await) which allows one to, for example, heap-allocate an async function frame:
+        \\
+        \\```zig
+        \\const std = @import("std");
+        \\test "heap allocated frame" {
+        \\    const frame = try std.heap.page_allocator.create(@Frame(func));
+        \\    frame.* = async func();
+        \\}
+        \\fn func() void {
+        \\    suspend {}
+        \\}
+        \\```
         ,
         .arguments = &.{
             "func: anytype",
@@ -817,8 +917,27 @@ pub const builtins = [_]Builtin{
         .signature = "@hasDecl(comptime Container: type, comptime name: []const u8) bool",
         .snippet = "@hasDecl(${1:comptime Container: type}, ${2:comptime name: []const u8})",
         .documentation =
-        \\Returns whether or not a [struct](https://ziglang.org/documentation/0.9.0/#struct), [enum](https://ziglang.org/documentation/0.9.0/#enum), or [union](https://ziglang.org/documentation/0.9.0/#union) has a declaration matching `name`.

{#code_begin|test|hasDecl#} const std = @import("std"); const expect = std.testing.expect; const Foo = struct { nope: i32, pub var blah = "xxx"; const hi = 1; }; test "@hasDecl" { try expect(@hasDecl(Foo, "blah")); // Even though `hi` is private, @hasDecl returns true because this test is // in the same file scope as Foo. It would return false if Foo was declared // in a different file. try expect(@hasDecl(Foo, "hi")); // @hasDecl is for declarations; not fields. try expect(!@hasDecl(Foo, "nope")); try expect(!@hasDecl(Foo, "nope1234")); }`
-        \\      
+        \\Returns whether or not a [struct](https://ziglang.org/documentation/0.9.0/#struct), [enum](https://ziglang.org/documentation/0.9.0/#enum), or [union](https://ziglang.org/documentation/0.9.0/#union) has a declaration matching `name`.
+        \\
+        \\```zig
+        \\const std = @import("std");
+        \\const expect = std.testing.expect;
+        \\const Foo = struct {
+        \\    nope: i32,
+        \\    pub var blah = "xxx";
+        \\    const hi = 1;
+        \\};
+        \\test "@hasDecl" {
+        \\    try expect(@hasDecl(Foo, "blah"));
+        \\    // Even though `hi` is private, @hasDecl returns true because this test is
+        \\    // in the same file scope as Foo. It would return false if Foo was declared
+        \\    // in a different file.
+        \\    try expect(@hasDecl(Foo, "hi"));
+        \\    // @hasDecl is for declarations; not fields.
+        \\    try expect(!@hasDecl(Foo, "nope"));
+        \\    try expect(!@hasDecl(Foo, "nope1234"));
+        \\}
+        \\```
         ,
         .arguments = &.{
             "comptime Container: type",
@@ -855,8 +974,10 @@ pub const builtins = [_]Builtin{
         \\`path` can be a relative path or it can be the name of a package. If it is a relative path, it is relative to the file that contains the `@import` function call.
         \\
         \\The following packages are always available:
-        \\  - `@import("std")` - Zig Standard Library
-        \\  - `@import("builtin")` - Target-specific information The command `zig build-exe --show-builtin` outputs the source to stdout for reference.
+        \\
+        \\ - `@import("std")` - Zig Standard Library
+        \\ - `@import("builtin")` - Target-specific information The command
+        \\`zig build-exe --show-builtin`outputs the source to stdout for reference.
         ,
         .arguments = &.{
             "comptime path: []u8",
@@ -893,7 +1014,7 @@ pub const builtins = [_]Builtin{
     .{
         .name = "@intToError",
         .signature = "@intToError(value: std.meta.Int(.unsigned, @sizeOf(anyerror) * 8)) anyerror",
-        .snippet = "@intToError(${1:value: std.meta.Int(.unsigned, @sizeOf(anyerror) * 8)})",
+        .snippet = "@intToError(${1:value: std.meta.Int(.unsigned, @sizeOf(anyerror) * 8})",
         .documentation =
         \\Converts from the integer representation of an error into [The Global Error Set](https://ziglang.org/documentation/0.9.0/#The-Global-Error-Set) type.
         \\
@@ -902,7 +1023,7 @@ pub const builtins = [_]Builtin{
         \\Attempting to convert an integer that does not correspond to any error results in safety-protected [Undefined Behavior](https://ziglang.org/documentation/0.9.0/#Undefined-Behavior).
         ,
         .arguments = &.{
-            "value: std.meta.Int(.unsigned, @sizeOf(anyerror) * 8)",
+            "value: std.meta.Int(.unsigned, @sizeOf(anyerror) * 8",
         },
     },
     .{
@@ -954,10 +1075,7 @@ pub const builtins = [_]Builtin{
         \\
         \\This function is a low level intrinsic with no safety mechanisms. Most code should not use this function, instead using something like this:
         \\
-        \\```zig
-        \\for (source[0..byte_count]) |b, i| dest[i] = b;
-        \\```
-        \\
+        \\`for (source[0..byte_count]) |b, i| dest[i] = b;`
         \\The optimizer is intelligent enough to turn the above snippet into a memcpy.
         \\
         \\There is also a standard library function for this:
@@ -982,10 +1100,7 @@ pub const builtins = [_]Builtin{
         \\
         \\This function is a low level intrinsic with no safety mechanisms. Most code should not use this function, instead using something like this:
         \\
-        \\```zig
-        \\for (dest[0..byte_count]) |*b| b.* = c;
-        \\```
-        \\
+        \\`for (dest[0..byte_count]) |*b| b.* = c;`
         \\The optimizer is intelligent enough to turn the above snippet into a memset.
         \\
         \\There is also a standard library function for this:
@@ -1035,8 +1150,19 @@ pub const builtins = [_]Builtin{
         .documentation =
         \\This function increases the size of the Wasm memory identified by `index` by `delta` in units of unsigned number of Wasm pages. Note that each Wasm page is 64KB in size. On success, returns previous memory size; on failure, if the allocation fails, returns -1.
         \\
-        \\This function is a low level intrinsic with no safety mechanisms usually useful for allocator designers targeting Wasm. So unless you are writing a new allocator from scratch, you should use something like `@import("std").heap.WasmPageAllocator`.

{#code_begin|test|wasmMemoryGrow#} const std = @import("std"); const native_arch = @import("builtin").target.cpu.arch; const expect = std.testing.expect; test "@wasmMemoryGrow" { if (native_arch != .wasm32) return error.SkipZigTest; var prev = @wasmMemorySize(0); try expect(prev == @wasmMemoryGrow(0, 1)); try expect(prev + 1 == @wasmMemorySize(0)); }`
-        \\      
+        \\This function is a low level intrinsic with no safety mechanisms usually useful for allocator designers targeting Wasm. So unless you are writing a new allocator from scratch, you should use something like `@import("std").heap.WasmPageAllocator`.
+        \\
+        \\```zig
+        \\const std = @import("std");
+        \\const native_arch = @import("builtin").target.cpu.arch;
+        \\const expect = std.testing.expect;
+        \\test "@wasmMemoryGrow" {
+        \\    if (native_arch != .wasm32) return error.SkipZigTest;
+        \\    var prev = @wasmMemorySize(0);
+        \\    try expect(prev == @wasmMemoryGrow(0, 1));
+        \\    try expect(prev + 1 == @wasmMemorySize(0));
+        \\}
+        \\```
         ,
         .arguments = &.{
             "index: u32",
@@ -1049,9 +1175,9 @@ pub const builtins = [_]Builtin{
         .snippet = "@mod(${1:numerator: T}, ${2:denominator: T})",
         .documentation =
         \\Modulus division. For unsigned integers this is the same as `numerator % denominator`. Caller guarantees `denominator > 0`.
-        \\  - `@mod(-5, 3) == 1`
-        \\  - `(@divFloor(a, b) * b) + @mod(a, b) == a`
         \\
+        \\ - `@mod(-5, 3) == 1`
+        \\ - `(@divFloor(a, b) * b) + @mod(a, b) == a`
         \\For a function that returns an error code, see `@import("std").math.mod`.
         ,
         .arguments = &.{
@@ -1081,8 +1207,9 @@ pub const builtins = [_]Builtin{
         \\Invokes the panic handler function. By default the panic handler function calls the public `panic` function exposed in the root source file, or if there is not one specified, the `std.builtin.default_panic` function from `std/builtin.zig`.
         \\
         \\Generally it is better to use `@import("std").debug.panic`. However, `@panic` can be useful for 2 scenarios:
-        \\  - From library code, calling the programmer's panic function if they exposed one in the root source file.
-        \\  - When mixing C and Zig code, calling the canonical panic implementation across multiple .o files.
+        \\
+        \\ - From library code, calling the programmer's panic function if they exposed one in the root source file.
+        \\ - When mixing C and Zig code, calling the canonical panic implementation across multiple .o files.
         ,
         .arguments = &.{
             "message: []const u8",
@@ -1115,7 +1242,32 @@ pub const builtins = [_]Builtin{
         \\
         \\The `ptr` argument may be any pointer type and determines the memory address to prefetch. This function does not dereference the pointer, it is perfectly legal to pass a pointer to invalid memory to this function and no illegal behavior will result.
         \\
-        \\The `options` argument is the following struct:

{#code_begin|syntax|builtin#} /// This data structure is used by the Zig language code generation and /// therefore must be kept in sync with the compiler implementation. pub const PrefetchOptions = struct { /// Whether the prefetch should prepare for a read or a write. rw: Rw = .read, /// 0 means no temporal locality. That is, the data can be immediately /// dropped from the cache after it is accessed. /// /// 3 means high temporal locality. That is, the data should be kept in /// the cache as it is likely to be accessed again soon. locality: u2 = 3, /// The cache that the prefetch should be preformed on. cache: Cache = .data, pub const Rw = enum { read, write, }; pub const Cache = enum { instruction, data, }; };`
+        \\The `options` argument is the following struct:
+        \\
+        \\```zig
+        \\/// This data structure is used by the Zig language code generation and
+        \\/// therefore must be kept in sync with the compiler implementation.
+        \\pub const PrefetchOptions = struct {
+        \\    /// Whether the prefetch should prepare for a read or a write.
+        \\    rw: Rw = .read,
+        \\    /// 0 means no temporal locality. That is, the data can be immediately
+        \\    /// dropped from the cache after it is accessed.
+        \\    ///
+        \\    /// 3 means high temporal locality. That is, the data should be kept in
+        \\    /// the cache as it is likely to be accessed again soon.
+        \\    locality: u2 = 3,
+        \\    /// The cache that the prefetch should be preformed on.
+        \\    cache: Cache = .data,
+        \\    pub const Rw = enum {
+        \\        read,
+        \\        write,
+        \\    };
+        \\    pub const Cache = enum {
+        \\        instruction,
+        \\        data,
+        \\    };
+        \\};
+        \\```
         ,
         .arguments = &.{
             "ptr: anytype",
@@ -1142,11 +1294,11 @@ pub const builtins = [_]Builtin{
         .snippet = "@ptrToInt(${1:value: anytype})",
         .documentation =
         \\Converts `value` to a `usize` which is the address of the pointer. `value` can be one of these types:
-        \\  - `*T`
-        \\  - `?*T`
-        \\  - `fn()`
-        \\  - `?fn()`
         \\
+        \\ - `*T`
+        \\ - `?*T`
+        \\ - `fn()`
+        \\ - `?fn()`
         \\To convert the other way, use [@intToPtr](https://ziglang.org/documentation/0.9.0/#intToPtr)
         ,
         .arguments = &.{
@@ -1159,9 +1311,9 @@ pub const builtins = [_]Builtin{
         .snippet = "@rem(${1:numerator: T}, ${2:denominator: T})",
         .documentation =
         \\Remainder division. For unsigned integers this is the same as `numerator % denominator`. Caller guarantees `denominator > 0`.
-        \\  - `@rem(-5, 3) == -2`
-        \\  - `(@divTrunc(a, b) * b) + @rem(a, b) == a`
         \\
+        \\ - `@rem(-5, 3) == -2`
+        \\ - `(@divTrunc(a, b) * b) + @rem(a, b) == a`
         \\For a function that returns an error code, see `@import("std").math.rem`.
         ,
         .arguments = &.{
@@ -1229,18 +1381,16 @@ pub const builtins = [_]Builtin{
         \\
         \\Example:
         \\
-        \\```zig
-        \\test "foo" {
-        \\    comptime {
-        \\        var i = 0;
-        \\        while (i < 1001) : (i += 1) {}
+        \\1001) : (i += 1) {}
         \\    }
         \\}
         \\```
+        \\Now we use `@setEvalBranchQuota`:
         \\
-        \\Now we use `@setEvalBranchQuota`:

{#code_begin|test|setEvalBranchQuota#} test "foo" { comptime { @setEvalBranchQuota(1001); var i = 0; while (i < 1001) : (i += 1) {} } }`
-        \\
-        \\      
+        \\1001) : (i += 1) {}
+        \\    }
+        \\}
+        \\```
         ,
         .arguments = &.{
             "new_quota: u32",
@@ -1259,16 +1409,16 @@ pub const builtins = [_]Builtin{
         \\    Optimized,
         \\};
         \\```
-        \\
-        \\  - `Strict` (default) - Floating point operations follow strict IEEE compliance.
-        \\  - `Optimized` - Floating point operations may do all of the following: 
    - \\ - Assume the arguments and result are not NaN. Optimizations are required to retain defined behavior over NaNs, but the value of the result is undefined. - \\ - Assume the arguments and result are not +/-Inf. Optimizations are required to retain defined behavior over +/-Inf, but the value of the result is undefined. - \\ - Treat the sign of a zero argument or result as insignificant. - \\ - Use the reciprocal of an argument rather than perform division. - \\ - Perform floating-point contraction (e.g. fusing a multiply followed by an addition into a fused multiply-and-add). - \\ - Perform algebraically equivalent transformations that may change results in floating point (e.g. reassociate). This is equivalent to `-ffast-math` in GCC.
- \\ + \\ - `Strict` (default) - Floating point operations follow strict IEEE compliance. + \\ - `Optimized` - Floating point operations may do all of the following: + \\ - Assume the arguments and result are not NaN. Optimizations are required to retain defined behavior over NaNs, but the value of the result is undefined. + \\ - Assume the arguments and result are not +/-Inf. Optimizations are required to retain defined behavior over +/-Inf, but the value of the result is undefined. + \\ - Treat the sign of a zero argument or result as insignificant. + \\ - Use the reciprocal of an argument rather than perform division. + \\ - Perform floating-point contraction (e.g. fusing a multiply followed by an addition into a fused multiply-and-add). + \\ - Perform algebraically equivalent transformations that may change results in floating point (e.g. reassociate). + \\This is equivalent to + \\`-ffast-math`in GCC. \\The floating point mode is inherited by child scopes, and can be overridden in any scope. You can set the floating point mode in a struct or module scope by using a comptime block. , .arguments = &.{ @@ -1294,7 +1444,6 @@ pub const builtins = [_]Builtin{ \\ @setRuntimeSafety(true); \\ var x: u8 = 255; \\ x += 1; - \\ \\ { \\ // The value can be overridden at any scope. So here integer overflow \\ // would not be caught in any build mode. @@ -1305,8 +1454,9 @@ pub const builtins = [_]Builtin{ \\ } \\} \\``` - \\ - \\Note: it is [planned](https://github.com/ziglang/zig/issues/978) to replace `@setRuntimeSafety` with `@optimizeFor` + \\Note: it is + \\[planned](https://github.com/ziglang/zig/issues/978)to replace `@setRuntimeSafety` with + \\`@optimizeFor` , .arguments = &.{ "safety_on: bool", @@ -1317,7 +1467,7 @@ pub const builtins = [_]Builtin{ .signature = "@shlExact(value: T, shift_amt: Log2T) T", .snippet = "@shlExact(${1:value: T}, ${2:shift_amt: Log2T})", .documentation = - \\Performs the left shift operation (`<<`). For unsigned integers, the result is [undefined](https://ziglang.org/documentation/0.9.0/#undefined) if any 1 bits are shifted out. For signed integers, the result is [undefined](https://ziglang.org/documentation/0.9.0/#undefined) if any bits that disagree with the resultant sign bit are shifted out. + \\`). For unsigned integers, the result is [undefined](https://ziglang.org/documentation/0.9.0/#undefined) if any 1 bits are shifted out. For signed integers, the result is [undefined](https://ziglang.org/documentation/0.9.0/#undefined) if any bits that disagree with the resultant sign bit are shifted out. \\ \\The type of `shift_amt` is an unsigned integer with `log2(T.bit_count)` bits. This is because `shift_amt >= T.bit_count` is undefined behavior. , @@ -1331,7 +1481,7 @@ pub const builtins = [_]Builtin{ .signature = "@shlWithOverflow(comptime T: type, a: T, shift_amt: Log2T, result: *T) bool", .snippet = "@shlWithOverflow(${1:comptime T: type}, ${2:a: T}, ${3:shift_amt: Log2T}, ${4:result: *T})", .documentation = - \\Performs `result.* = a << b`. If overflow or underflow occurs, stores the overflowed bits in `result` and returns `true`. If no overflow or underflow occurs, returns `false`. + \\b`. If overflow or underflow occurs, stores the overflowed bits in `result` and returns `true`. If no overflow or underflow occurs, returns `false`. \\ \\The type of `shift_amt` is an unsigned integer with `log2(T.bit_count)` bits. This is because `shift_amt >= T.bit_count` is undefined behavior. , @@ -1371,8 +1521,26 @@ pub const builtins = [_]Builtin{ \\ \\If `a` or `b` is `undefined`, it is equivalent to a vector of all `undefined` with the same length as the other vector. If both vectors are `undefined`, `@shuffle` returns a vector with all elements `undefined`. \\ - \\`E` must be an [integer](https://ziglang.org/documentation/0.9.0/#Integers), [float](https://ziglang.org/documentation/0.9.0/#Floats), [pointer](https://ziglang.org/documentation/0.9.0/#Pointers), or `bool`. The mask may be any vector length, and its length determines the result length.

{#code_begin|test|vector_shuffle#} const std = @import("std"); const Vector = std.meta.Vector; const expect = std.testing.expect; test "vector @shuffle" { const a: Vector(7, u8) = [_]u8{ 'o', 'l', 'h', 'e', 'r', 'z', 'w' }; const b: Vector(4, u8) = [_]u8{ 'w', 'd', '!', 'x' }; // To shuffle within a single vector, pass undefined as the second argument. // Notice that we can re-order, duplicate, or omit elements of the input vector const mask1: Vector(5, i32) = [_]i32{ 2, 3, 1, 1, 0 }; const res1: Vector(5, u8) = @shuffle(u8, a, undefined, mask1); try expect(std.mem.eql(u8, &@as([5]u8, res1), "hello")); // Combining two vectors const mask2: Vector(6, i32) = [_]i32{ -1, 0, 4, 1, -2, -3 }; const res2: Vector(6, u8) = @shuffle(u8, a, b, mask2); try expect(std.mem.eql(u8, &@as([6]u8, res2), "world!")); }`
-        \\      
+        \\`E` must be an [integer](https://ziglang.org/documentation/0.9.0/#Integers), [float](https://ziglang.org/documentation/0.9.0/#Floats), [pointer](https://ziglang.org/documentation/0.9.0/#Pointers), or `bool`. The mask may be any vector length, and its length determines the result length.
+        \\
+        \\```zig
+        \\const std = @import("std");
+        \\const Vector = std.meta.Vector;
+        \\const expect = std.testing.expect;
+        \\test "vector @shuffle" {
+        \\    const a: Vector(7, u8) = [_]u8{ 'o', 'l', 'h', 'e', 'r', 'z', 'w' };
+        \\    const b: Vector(4, u8) = [_]u8{ 'w', 'd', '!', 'x' };
+        \\    // To shuffle within a single vector, pass undefined as the second argument.
+        \\    // Notice that we can re-order, duplicate, or omit elements of the input vector
+        \\    const mask1: Vector(5, i32) = [_]i32{ 2, 3, 1, 1, 0 };
+        \\    const res1: Vector(5, u8) = @shuffle(u8, a, undefined, mask1);
+        \\    try expect(std.mem.eql(u8, &@as([5]u8, res1), "hello"));
+        \\    // Combining two vectors
+        \\    const mask2: Vector(6, i32) = [_]i32{ -1, 0, 4, 1, -2, -3 };
+        \\    const res2: Vector(6, u8) = @shuffle(u8, a, b, mask2);
+        \\    try expect(std.mem.eql(u8, &@as([6]u8, res2), "world!"));
+        \\}
+        \\```
         ,
         .arguments = &.{
             "comptime E: type",
@@ -1401,14 +1569,19 @@ pub const builtins = [_]Builtin{
         .signature = "@splat(comptime len: u32, scalar: anytype) std.meta.Vector(len, @TypeOf(scalar))",
         .snippet = "@splat(${1:comptime len: u32}, ${2:scalar: anytype})",
         .documentation =
-        \\Produces a vector of length `len` where each element is the value `scalar`:

{#code_begin|test|vector_splat#} const std = @import("std"); const expect = std.testing.expect; test "vector @splat" { const scalar: u32 = 5; const result = @splat(4, scalar); comptime try expect(@TypeOf(result) == std.meta.Vector(4, u32)); try expect(std.mem.eql(u32, &@as([4]u32, result), &[_]u32{ 5, 5, 5, 5 })); }`
-        \\      
+        \\Produces a vector of length `len` where each element is the value `scalar`:
         \\
-        \\
-        \\      `scalar` must be an [integer](https://ziglang.org/documentation/0.9.0/#Integers), [bool](https://ziglang.org/documentation/0.9.0/#Primitive-Types),
-        \\      [float](https://ziglang.org/documentation/0.9.0/#Floats), or [pointer](https://ziglang.org/documentation/0.9.0/#Pointers).
-        \\      

- \\ + \\```zig + \\const std = @import("std"); + \\const expect = std.testing.expect; + \\test "vector @splat" { + \\ const scalar: u32 = 5; + \\ const result = @splat(4, scalar); + \\ comptime try expect(@TypeOf(result) == std.meta.Vector(4, u32)); + \\ try expect(std.mem.eql(u32, &@as([4]u32, result), &[_]u32{ 5, 5, 5, 5 })); + \\} + \\``` + \\`scalar` must be an [integer](https://ziglang.org/documentation/0.9.0/#Integers), [bool](https://ziglang.org/documentation/0.9.0/#Primitive-Types), [float](https://ziglang.org/documentation/0.9.0/#Floats), or [pointer](https://ziglang.org/documentation/0.9.0/#Pointers). , .arguments = &.{ "comptime len: u32", @@ -1423,12 +1596,25 @@ pub const builtins = [_]Builtin{ \\Transforms a [vector](https://ziglang.org/documentation/0.9.0/#Vectors) into a scalar value by performing a sequential horizontal reduction of its elements using the specified operator `op`. \\ \\Not every operator is available for every vector element type: - \\ - `.And`, `.Or`, `.Xor` are available for `bool` vectors, - \\ - `.Min`, `.Max`, `.Add`, `.Mul` are available for [floating point](https://ziglang.org/documentation/0.9.0/#Floats) vectors, - \\ - Every operator is available for [integer](https://ziglang.org/documentation/0.9.0/#Integers) vectors. \\ - \\Note that `.Add` and `.Mul` reductions on integral types are wrapping; when applied on floating point types the operation associativity is preserved, unless the float mode is set to `Optimized`.

{#code_begin|test|vector_reduce#} const std = @import("std"); const expect = std.testing.expect; test "vector @reduce" { const value: std.meta.Vector(4, i32) = [_]i32{ 1, -1, 1, -1 }; const result = value > @splat(4, @as(i32, 0)); // result is { true, false, true, false }; comptime try expect(@TypeOf(result) == std.meta.Vector(4, bool)); const is_all_true = @reduce(.And, result); comptime try expect(@TypeOf(is_all_true) == bool); try expect(is_all_true == false); }`
-        \\      
+        \\ - `.And`, `.Or`, `.Xor` are available for `bool` vectors,
+        \\ - `.Min`, `.Max`, `.Add`, `.Mul` are available for [floating point](https://ziglang.org/documentation/0.9.0/#Floats) vectors,
+        \\ - Every operator is available for [integer](https://ziglang.org/documentation/0.9.0/#Integers) vectors.
+        \\Note that `.Add` and `.Mul` reductions on integral types are wrapping; when applied on floating point types the operation associativity is preserved, unless the float mode is set to `Optimized`.
+        \\
+        \\```zig
+        \\const std = @import("std");
+        \\const expect = std.testing.expect;
+        \\test "vector @reduce" {
+        \\    const value: std.meta.Vector(4, i32) = [_]i32{ 1, -1, 1, -1 };
+        \\    const result = value > @splat(4, @as(i32, 0));
+        \\    // result is { true, false, true, false };
+        \\    comptime try expect(@TypeOf(result) == std.meta.Vector(4, bool));
+        \\    const is_all_true = @reduce(.And, result);
+        \\    comptime try expect(@TypeOf(is_all_true) == bool);
+        \\    try expect(is_all_true == false);
+        \\}
+        \\```
         ,
         .arguments = &.{
             "comptime op: std.builtin.ReduceOp",
@@ -1440,7 +1626,22 @@ pub const builtins = [_]Builtin{
         .signature = "@src() std.builtin.SourceLocation",
         .snippet = "@src()",
         .documentation =
-        \\Returns a `SourceLocation` struct representing the function's name and location in the source code. This must be called in a function.

{#code_begin|test|source_location#} const std = @import("std"); const expect = std.testing.expect; test "@src" { try doTheTest(); } fn doTheTest() !void { const src = @src(); try expect(src.line == 9); try expect(src.column == 17); try expect(std.mem.endsWith(u8, src.fn_name, "doTheTest")); try expect(std.mem.endsWith(u8, src.file, "source_location.zig")); }`
+        \\Returns a `SourceLocation` struct representing the function's name and location in the source code. This must be called in a function.
+        \\
+        \\```zig
+        \\const std = @import("std");
+        \\const expect = std.testing.expect;
+        \\test "@src" {
+        \\    try doTheTest();
+        \\}
+        \\fn doTheTest() !void {
+        \\    const src = @src();
+        \\    try expect(src.line == 9);
+        \\    try expect(src.column == 17);
+        \\    try expect(std.mem.endsWith(u8, src.fn_name, "doTheTest"));
+        \\    try expect(std.mem.endsWith(u8, src.file, "source_location.zig"));
+        \\}
+        \\```
         ,
         .arguments = &.{},
     },
@@ -1451,7 +1652,8 @@ pub const builtins = [_]Builtin{
         .documentation =
         \\Performs the square root of a floating point number. Uses a dedicated hardware instruction when available.
         \\
-        \\Supports [Floats](https://ziglang.org/documentation/0.9.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.9.0/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
+        \\Supports [Floats](https://ziglang.org/documentation/0.9.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.9.0/#Vectors) of floats, with the caveat that
+        \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
         ,
         .arguments = &.{
             "value: anytype",
@@ -1464,7 +1666,8 @@ pub const builtins = [_]Builtin{
         .documentation =
         \\Sine trigonometric function on a floating point number. Uses a dedicated hardware instruction when available.
         \\
-        \\Supports [Floats](https://ziglang.org/documentation/0.9.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.9.0/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
+        \\Supports [Floats](https://ziglang.org/documentation/0.9.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.9.0/#Vectors) of floats, with the caveat that
+        \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
         ,
         .arguments = &.{
             "value: anytype",
@@ -1477,7 +1680,8 @@ pub const builtins = [_]Builtin{
         .documentation =
         \\Cosine trigonometric function on a floating point number. Uses a dedicated hardware instruction when available.
         \\
-        \\Supports [Floats](https://ziglang.org/documentation/0.9.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.9.0/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
+        \\Supports [Floats](https://ziglang.org/documentation/0.9.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.9.0/#Vectors) of floats, with the caveat that
+        \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
         ,
         .arguments = &.{
             "value: anytype",
@@ -1490,7 +1694,8 @@ pub const builtins = [_]Builtin{
         .documentation =
         \\Base-e exponential function on a floating point number. Uses a dedicated hardware instruction when available.
         \\
-        \\Supports [Floats](https://ziglang.org/documentation/0.9.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.9.0/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
+        \\Supports [Floats](https://ziglang.org/documentation/0.9.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.9.0/#Vectors) of floats, with the caveat that
+        \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
         ,
         .arguments = &.{
             "value: anytype",
@@ -1503,7 +1708,8 @@ pub const builtins = [_]Builtin{
         .documentation =
         \\Base-2 exponential function on a floating point number. Uses a dedicated hardware instruction when available.
         \\
-        \\Supports [Floats](https://ziglang.org/documentation/0.9.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.9.0/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
+        \\Supports [Floats](https://ziglang.org/documentation/0.9.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.9.0/#Vectors) of floats, with the caveat that
+        \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
         ,
         .arguments = &.{
             "value: anytype",
@@ -1516,7 +1722,8 @@ pub const builtins = [_]Builtin{
         .documentation =
         \\Returns the natural logarithm of a floating point number. Uses a dedicated hardware instruction when available.
         \\
-        \\Supports [Floats](https://ziglang.org/documentation/0.9.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.9.0/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
+        \\Supports [Floats](https://ziglang.org/documentation/0.9.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.9.0/#Vectors) of floats, with the caveat that
+        \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
         ,
         .arguments = &.{
             "value: anytype",
@@ -1529,7 +1736,8 @@ pub const builtins = [_]Builtin{
         .documentation =
         \\Returns the logarithm to the base 2 of a floating point number. Uses a dedicated hardware instruction when available.
         \\
-        \\Supports [Floats](https://ziglang.org/documentation/0.9.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.9.0/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
+        \\Supports [Floats](https://ziglang.org/documentation/0.9.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.9.0/#Vectors) of floats, with the caveat that
+        \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
         ,
         .arguments = &.{
             "value: anytype",
@@ -1542,7 +1750,8 @@ pub const builtins = [_]Builtin{
         .documentation =
         \\Returns the logarithm to the base 10 of a floating point number. Uses a dedicated hardware instruction when available.
         \\
-        \\Supports [Floats](https://ziglang.org/documentation/0.9.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.9.0/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
+        \\Supports [Floats](https://ziglang.org/documentation/0.9.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.9.0/#Vectors) of floats, with the caveat that
+        \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
         ,
         .arguments = &.{
             "value: anytype",
@@ -1555,7 +1764,8 @@ pub const builtins = [_]Builtin{
         .documentation =
         \\Returns the absolute value of a floating point number. Uses a dedicated hardware instruction when available.
         \\
-        \\Supports [Floats](https://ziglang.org/documentation/0.9.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.9.0/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
+        \\Supports [Floats](https://ziglang.org/documentation/0.9.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.9.0/#Vectors) of floats, with the caveat that
+        \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
         ,
         .arguments = &.{
             "value: anytype",
@@ -1568,7 +1778,8 @@ pub const builtins = [_]Builtin{
         .documentation =
         \\Returns the largest integral value not greater than the given floating point number. Uses a dedicated hardware instruction when available.
         \\
-        \\Supports [Floats](https://ziglang.org/documentation/0.9.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.9.0/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
+        \\Supports [Floats](https://ziglang.org/documentation/0.9.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.9.0/#Vectors) of floats, with the caveat that
+        \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
         ,
         .arguments = &.{
             "value: anytype",
@@ -1581,7 +1792,8 @@ pub const builtins = [_]Builtin{
         .documentation =
         \\Returns the smallest integral value not less than the given floating point number. Uses a dedicated hardware instruction when available.
         \\
-        \\Supports [Floats](https://ziglang.org/documentation/0.9.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.9.0/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
+        \\Supports [Floats](https://ziglang.org/documentation/0.9.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.9.0/#Vectors) of floats, with the caveat that
+        \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
         ,
         .arguments = &.{
             "value: anytype",
@@ -1594,7 +1806,8 @@ pub const builtins = [_]Builtin{
         .documentation =
         \\Rounds the given floating point number to an integer, towards zero. Uses a dedicated hardware instruction when available.
         \\
-        \\Supports [Floats](https://ziglang.org/documentation/0.9.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.9.0/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
+        \\Supports [Floats](https://ziglang.org/documentation/0.9.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.9.0/#Vectors) of floats, with the caveat that
+        \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
         ,
         .arguments = &.{
             "value: anytype",
@@ -1607,7 +1820,8 @@ pub const builtins = [_]Builtin{
         .documentation =
         \\Rounds the given floating point number to an integer, away from zero. Uses a dedicated hardware instruction when available.
         \\
-        \\Supports [Floats](https://ziglang.org/documentation/0.9.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.9.0/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
+        \\Supports [Floats](https://ziglang.org/documentation/0.9.0/#Floats) and [Vectors](https://ziglang.org/documentation/0.9.0/#Vectors) of floats, with the caveat that
+        \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026).
         ,
         .arguments = &.{
             "value: anytype",
@@ -1645,13 +1859,27 @@ pub const builtins = [_]Builtin{
         .signature = "@This() type",
         .snippet = "@This()",
         .documentation =
-        \\Returns the innermost struct, enum, or union that this function call is inside. This can be useful for an anonymous struct that needs to refer to itself:

{#code_begin|test|this_innermost#} const std = @import("std"); const expect = std.testing.expect; test "@This()" { var items = [_]i32{ 1, 2, 3, 4 }; const list = List(i32){ .items = items[0..] }; try expect(list.length() == 4); } fn List(comptime T: type) type { return struct { const Self = @This(); items: []T, fn length(self: Self) usize { return self.items.len; } }; }`
-        \\      
+        \\Returns the innermost struct, enum, or union that this function call is inside. This can be useful for an anonymous struct that needs to refer to itself:
         \\
-        \\
-        \\      When `@This()` is used at file scope, it returns a reference to the
-        \\      struct that corresponds to the current file.
-        \\      
+        \\```zig
+        \\const std = @import("std");
+        \\const expect = std.testing.expect;
+        \\test "@This()" {
+        \\    var items = [_]i32{ 1, 2, 3, 4 };
+        \\    const list = List(i32){ .items = items[0..] };
+        \\    try expect(list.length() == 4);
+        \\}
+        \\fn List(comptime T: type) type {
+        \\    return struct {
+        \\        const Self = @This();
+        \\        items: []T,
+        \\        fn length(self: Self) usize {
+        \\            return self.items.len;
+        \\        }
+        \\    };
+        \\}
+        \\```
+        \\When `@This()` is used at file scope, it returns a reference to the struct that corresponds to the current file.
         ,
         .arguments = &.{},
     },
@@ -1671,20 +1899,17 @@ pub const builtins = [_]Builtin{
         \\    _ = b;
         \\}
         \\```
-        \\
         \\However this is well defined and working code:
         \\
         \\```zig
         \\const std = @import("std");
         \\const expect = std.testing.expect;
-        \\
         \\test "integer truncation" {
         \\    var a: u16 = 0xabcd;
         \\    var b: u8 = @truncate(u8, a);
         \\    try expect(b == 0xcd);
         \\}
         \\```
-        \\
         \\This function always truncates the significant bits of the integer, regardless of endianness on the target platform.
         ,
         .arguments = &.{
@@ -1700,33 +1925,34 @@ pub const builtins = [_]Builtin{
         \\This function is the inverse of [@typeInfo](https://ziglang.org/documentation/0.9.0/#typeInfo). It reifies type information into a `type`.
         \\
         \\It is available for the following types:
-        \\  - `type`
-        \\  - `noreturn`
-        \\  - `void`
-        \\  - `bool`
-        \\  - [Integers](https://ziglang.org/documentation/0.9.0/#Integers) - The maximum bit count for an integer type is `65535`.
-        \\  - [Floats](https://ziglang.org/documentation/0.9.0/#Floats)
-        \\  - [Pointers](https://ziglang.org/documentation/0.9.0/#Pointers)
-        \\  - `comptime_int`
-        \\  - `comptime_float`
-        \\  - `@TypeOf(undefined)`
-        \\  - `@TypeOf(null)`
-        \\  - [Arrays](https://ziglang.org/documentation/0.9.0/#Arrays)
-        \\  - [Optionals](https://ziglang.org/documentation/0.9.0/#Optionals)
-        \\  - [Error Set Type](https://ziglang.org/documentation/0.9.0/#Error-Set-Type)
-        \\  - [Error Union Type](https://ziglang.org/documentation/0.9.0/#Error-Union-Type)
-        \\  - [Vectors](https://ziglang.org/documentation/0.9.0/#Vectors)
-        \\  - [opaque](https://ziglang.org/documentation/0.9.0/#opaque)
-        \\  - [@Frame](https://ziglang.org/documentation/0.9.0/#Frame)
-        \\  - `anyframe`
-        \\  - [struct](https://ziglang.org/documentation/0.9.0/#struct)
-        \\  - [enum](https://ziglang.org/documentation/0.9.0/#enum)
-        \\  - [Enum Literals](https://ziglang.org/documentation/0.9.0/#Enum-Literals)
-        \\  - [union](https://ziglang.org/documentation/0.9.0/#union)
         \\
+        \\ - `type`
+        \\ - `noreturn`
+        \\ - `void`
+        \\ - `bool`
+        \\ - [Integers](https://ziglang.org/documentation/0.9.0/#Integers) - The maximum bit count for an integer type is `65535`.
+        \\ - [Floats](https://ziglang.org/documentation/0.9.0/#Floats)
+        \\ - [Pointers](https://ziglang.org/documentation/0.9.0/#Pointers)
+        \\ - `comptime_int`
+        \\ - `comptime_float`
+        \\ - `@TypeOf(undefined)`
+        \\ - `@TypeOf(null)`
+        \\ - [Arrays](https://ziglang.org/documentation/0.9.0/#Arrays)
+        \\ - [Optionals](https://ziglang.org/documentation/0.9.0/#Optionals)
+        \\ - [Error Set Type](https://ziglang.org/documentation/0.9.0/#Error-Set-Type)
+        \\ - [Error Union Type](https://ziglang.org/documentation/0.9.0/#Error-Union-Type)
+        \\ - [Vectors](https://ziglang.org/documentation/0.9.0/#Vectors)
+        \\ - [opaque](https://ziglang.org/documentation/0.9.0/#opaque)
+        \\ - [@Frame](https://ziglang.org/documentation/0.9.0/#Frame)
+        \\ - `anyframe`
+        \\ - [struct](https://ziglang.org/documentation/0.9.0/#struct)
+        \\ - [enum](https://ziglang.org/documentation/0.9.0/#enum)
+        \\ - [Enum Literals](https://ziglang.org/documentation/0.9.0/#Enum-Literals)
+        \\ - [union](https://ziglang.org/documentation/0.9.0/#union)
         \\For these types, `@Type` is not available:
-        \\  - [Functions](https://ziglang.org/documentation/0.9.0/#Functions)
-        \\  - BoundFn
+        \\
+        \\ - [Functions](https://ziglang.org/documentation/0.9.0/#Functions)
+        \\ - BoundFn
         ,
         .arguments = &.{
             "comptime info: std.builtin.TypeInfo",
@@ -1763,7 +1989,23 @@ pub const builtins = [_]Builtin{
         .documentation =
         \\`@TypeOf` is a special builtin function that takes any (nonzero) number of expressions as parameters and returns the type of the result, using [Peer Type Resolution](https://ziglang.org/documentation/0.9.0/#Peer-Type-Resolution).
         \\
-        \\The expressions are evaluated, however they are guaranteed to have no *runtime* side-effects:

{#code_begin|test|no_runtime_side_effects#} const std = @import("std"); const expect = std.testing.expect; test "no runtime side effects" { var data: i32 = 0; const T = @TypeOf(foo(i32, &data)); comptime try expect(T == i32); try expect(data == 0); } fn foo(comptime T: type, ptr: *T) T { ptr.* += 1; return ptr.*; }`
+        \\The expressions are evaluated, however they are guaranteed to have no
+        \\**runtime** side-effects:
+        \\
+        \\```zig
+        \\const std = @import("std");
+        \\const expect = std.testing.expect;
+        \\test "no runtime side effects" {
+        \\    var data: i32 = 0;
+        \\    const T = @TypeOf(foo(i32, &data));
+        \\    comptime try expect(T == i32);
+        \\    try expect(data == 0);
+        \\}
+        \\fn foo(comptime T: type, ptr: *T) T {
+        \\    ptr.* += 1;
+        \\    return ptr.*;
+        \\}
+        \\```
         ,
         .arguments = &.{
             "...",
@@ -1785,3 +2027,5 @@ pub const builtins = [_]Builtin{
         },
     },
 };
+
+// DO NOT EDIT
diff --git a/src/data/0.9.1.zig b/src/data/0.9.1.zig
index da1eddd..4a01f02 100644
--- a/src/data/0.9.1.zig
+++ b/src/data/0.9.1.zig
@@ -1,3 +1,8 @@
+//! DO NOT EDIT
+//! If you want to update this file run:
+//! `zig build gen -- --generate-version-data 0.9.1` (requires an internet connection)
+//! GENERATED BY src/config_gen/config_gen.zig
+
 const Builtin = struct {
     name: []const u8,
     signature: []const u8,
@@ -48,8 +53,7 @@ pub const builtins = [_]Builtin{
         \\    assert(*u32 == *align(@alignOf(u32)) u32);
         \\}
         \\```
-        \\
-        \\The result is a target-specific compile time constant. It is guaranteed to be less than or equal to [@sizeOf(T)](https://ziglang.org/documentation/0.9.1/#@sizeOf).
+        \\The result is a target-specific compile time constant. It is guaranteed to be less than or equal to [@sizeOf(T)](https://ziglang.org/documentation/0.9.1/#sizeOf).
         ,
         .arguments = &.{
             "comptime T: type",
@@ -70,19 +74,38 @@ pub const builtins = [_]Builtin{
     .{
         .name = "@asyncCall",
         .signature = "@asyncCall(frame_buffer: []align(@alignOf(@Frame(anyAsyncFunction))) u8, result_ptr, function_ptr, args: anytype) anyframe->T",
-        .snippet = "@asyncCall(${1:frame_buffer: []align(@alignOf(@Frame(anyAsyncFunction))) u8}, ${2:result_ptr}, ${3:function_ptr}, ${4:args: anytype})",
+        .snippet = "@asyncCall(${1:frame_buffer: []align(@alignOf(@Frame(anyAsyncFunction)})",
         .documentation =
         \\`@asyncCall` performs an `async` call on a function pointer, which may or may not be an [async function](https://ziglang.org/documentation/0.9.1/#Async-Functions).
         \\
         \\The provided `frame_buffer` must be large enough to fit the entire function frame. This size can be determined with [@frameSize](https://ziglang.org/documentation/0.9.1/#frameSize). To provide a too-small buffer invokes safety-checked [Undefined Behavior](https://ziglang.org/documentation/0.9.1/#Undefined-Behavior).
         \\
-        \\`result_ptr` is optional ([null](https://ziglang.org/documentation/0.9.1/#null) may be provided). If provided, the function call will write its result directly to the result pointer, which will be available to read after [await](https://ziglang.org/documentation/0.9.1/#Async-and-Await) completes. Any result location provided to `await` will copy the result from `result_ptr`.

{#code_begin|test|async_struct_field_fn_pointer#} const std = @import("std"); const expect = std.testing.expect; test "async fn pointer in a struct field" { var data: i32 = 1; const Foo = struct { bar: fn (*i32) callconv(.Async) void, }; var foo = Foo{ .bar = func }; var bytes: [64]u8 align(@alignOf(@Frame(func))) = undefined; const f = @asyncCall(&bytes, {}, foo.bar, .{&data}); try expect(data == 2); resume f; try expect(data == 4); } fn func(y: *i32) void { defer y.* += 2; y.* += 1; suspend {} }` + \\`result_ptr` is optional ([null](https://ziglang.org/documentation/0.9.1/#null) may be provided). If provided, the function call will write its result directly to the result pointer, which will be available to read after [await](https://ziglang.org/documentation/0.9.1/#Async-and-Await) completes. Any result location provided to `await` will copy the result from `result_ptr`. + \\ + \\```zig + \\const std = @import("std"); + \\const expect = std.testing.expect; + \\test "async fn pointer in a struct field" { + \\ var data: i32 = 1; + \\ const Foo = struct { + \\ bar: fn (*i32) callconv(.Async) void, + \\ }; + \\ var foo = Foo{ .bar = func }; + \\ var bytes: [64]u8 align(@alignOf(@Frame(func))) = undefined; + \\ const f = @asyncCall(&bytes, {}, foo.bar, .{&data}); + \\ try expect(data == 2); + \\ resume f; + \\ try expect(data == 4); + \\} + \\fn func(y: *i32) void { + \\ defer y.* += 2; + \\ y.* += 1; + \\ suspend {} + \\} + \\``` , .arguments = &.{ - "frame_buffer: []align(@alignOf(@Frame(anyAsyncFunction))) u8", - "result_ptr", - "function_ptr", - "args: anytype", + "frame_buffer: []align(@alignOf(@Frame(anyAsyncFunction)", }, }, .{ @@ -110,15 +133,16 @@ pub const builtins = [_]Builtin{ \\`T` must be a pointer, a `bool`, a float, an integer or an enum. \\ \\Supported operations: - \\ - `.Xchg` - stores the operand unmodified. Supports enums, integers and floats. - \\ - `.Add` - for integers, twos complement wraparound addition. Also supports [Floats](https://ziglang.org/documentation/0.9.1/#Floats). - \\ - `.Sub` - for integers, twos complement wraparound subtraction. Also supports [Floats](https://ziglang.org/documentation/0.9.1/#Floats). - \\ - `.And` - bitwise and - \\ - `.Nand` - bitwise nand - \\ - `.Or` - bitwise or - \\ - `.Xor` - bitwise xor - \\ - `.Max` - stores the operand if it is larger. Supports integers and floats. - \\ - `.Min` - stores the operand if it is smaller. Supports integers and floats. + \\ + \\ - `.Xchg` - stores the operand unmodified. Supports enums, integers and floats. + \\ - `.Add` - for integers, twos complement wraparound addition. Also supports [Floats](https://ziglang.org/documentation/0.9.1/#Floats). + \\ - `.Sub` - for integers, twos complement wraparound subtraction. Also supports [Floats](https://ziglang.org/documentation/0.9.1/#Floats). + \\ - `.And` - bitwise and + \\ - `.Nand` - bitwise nand + \\ - `.Or` - bitwise or + \\ - `.Xor` - bitwise xor + \\ - `.Max` - stores the operand if it is larger. Supports integers and floats. + \\ - `.Min` - stores the operand if it is smaller. Supports integers and floats. , .arguments = &.{ "comptime T: type", @@ -156,9 +180,9 @@ pub const builtins = [_]Builtin{ \\Asserts that `@typeInfo(DestType) != .Pointer`. Use `@ptrCast` or `@intToPtr` if you need this. \\ \\Can be used for these things for example: - \\ - Convert `f32` to `u32` bits - \\ - Convert `i32` to `u32` preserving twos complement \\ + \\ - Convert `f32` to `u32` bits + \\ - Convert `i32` to `u32` preserving twos complement \\Works at compile-time if `value` is known at compile time. It's a compile error to bitcast a struct to a scalar type of the same size since structs have undefined layout. However if the struct is packed then it works. , .arguments = &.{ @@ -288,17 +312,48 @@ pub const builtins = [_]Builtin{ \\ \\```zig \\const expect = @import("std").testing.expect; - \\ \\test "noinline function call" { \\ try expect(@call(.{}, add, .{3, 9}) == 12); \\} - \\ \\fn add(a: i32, b: i32) i32 { \\ return a + b; \\} \\``` + \\`@call` allows more flexibility than normal function call syntax does. The `CallOptions` struct is reproduced here: \\ - \\`@call` allows more flexibility than normal function call syntax does. The `CallOptions` struct is reproduced here:

{#syntax_block|zig|builtin.CallOptions struct#} pub const CallOptions = struct { modifier: Modifier = .auto, /// Only valid when `Modifier` is `Modifier.async_kw`. stack: ?[]align(std.Target.stack_align) u8 = null, pub const Modifier = enum { /// Equivalent to function call syntax. auto, /// Equivalent to async keyword used with function call syntax. async_kw, /// Prevents tail call optimization. This guarantees that the return /// address will point to the callsite, as opposed to the callsite's /// callsite. If the call is otherwise required to be tail-called /// or inlined, a compile error is emitted instead. never_tail, /// Guarantees that the call will not be inlined. If the call is /// otherwise required to be inlined, a compile error is emitted instead. never_inline, /// Asserts that the function call will not suspend. This allows a /// non-async function to call an async function. no_async, /// Guarantees that the call will be generated with tail call optimization. /// If this is not possible, a compile error is emitted instead. always_tail, /// Guarantees that the call will inlined at the callsite. /// If this is not possible, a compile error is emitted instead. always_inline, /// Evaluates the call at compile-time. If the call cannot be completed at /// compile-time, a compile error is emitted instead. compile_time, }; }; {#end_syntax_block#} + \\```zig + \\pub const CallOptions = struct { + \\ modifier: Modifier = .auto, + \\ /// Only valid when `Modifier` is `Modifier.async_kw`. + \\ stack: ?[]align(std.Target.stack_align) u8 = null, + \\ pub const Modifier = enum { + \\ /// Equivalent to function call syntax. + \\ auto, + \\ /// Equivalent to async keyword used with function call syntax. + \\ async_kw, + \\ /// Prevents tail call optimization. This guarantees that the return + \\ /// address will point to the callsite, as opposed to the callsite's + \\ /// callsite. If the call is otherwise required to be tail-called + \\ /// or inlined, a compile error is emitted instead. + \\ never_tail, + \\ /// Guarantees that the call will not be inlined. If the call is + \\ /// otherwise required to be inlined, a compile error is emitted instead. + \\ never_inline, + \\ /// Asserts that the function call will not suspend. This allows a + \\ /// non-async function to call an async function. + \\ no_async, + \\ /// Guarantees that the call will be generated with tail call optimization. + \\ /// If this is not possible, a compile error is emitted instead. + \\ always_tail, + \\ /// Guarantees that the call will inlined at the callsite. + \\ /// If this is not possible, a compile error is emitted instead. + \\ always_inline, + \\ /// Evaluates the call at compile-time. If the call cannot be completed at + \\ /// compile-time, a compile error is emitted instead. + \\ compile_time, + \\ }; + \\}; + \\``` , .arguments = &.{ "options: std.builtin.CallOptions", @@ -313,15 +368,14 @@ pub const builtins = [_]Builtin{ .documentation = \\This function can only occur inside `@cImport`. \\ - \\This appends `#define $name $value` to the `@cImport` temporary buffer. + \\This appends + \\`#define $name $value`to the `@cImport` temporary buffer. \\ - \\To define without a value, like this:`#define _GNU_SOURCE` + \\To define without a value, like this: \\ - \\Use the void value, like this: + \\`#define _GNU_SOURCE`Use the void value, like this: \\ - \\```zig - \\@cDefine("_GNU_SOURCE", {}) - \\``` + \\`@cDefine("_GNU_SOURCE", {})` , .arguments = &.{ "comptime name: []u8", @@ -340,8 +394,9 @@ pub const builtins = [_]Builtin{ \\Usually you should only have one `@cImport` in your entire application, because it saves the compiler from invoking clang multiple times, and prevents inline functions from being duplicated. \\ \\Reasons for having multiple `@cImport` expressions would be: - \\ - To avoid a symbol collision, for example if foo.h and bar.h both `#define CONNECTION_COUNT` - \\ - To analyze the C code with different preprocessor defines + \\ + \\ - To avoid a symbol collision, for example if foo.h and bar.h both + \\`#define CONNECTION_COUNT` - To analyze the C code with different preprocessor defines , .arguments = &.{ "expression", @@ -354,7 +409,8 @@ pub const builtins = [_]Builtin{ .documentation = \\This function can only occur inside `@cImport`. \\ - \\This appends `#include <$path>\n` to the `c_import` temporary buffer. + \\This appends + \\`#include <$path>\n`to the `c_import` temporary buffer. , .arguments = &.{ "comptime path: []u8", @@ -398,7 +454,6 @@ pub const builtins = [_]Builtin{ \\ } \\} \\``` - \\ \\If you are using cmpxchg in a loop, [@cmpxchgWeak](https://ziglang.org/documentation/0.9.1/#cmpxchgWeak) is the better choice, because it can be implemented more efficiently in machine instructions. \\ \\`T` must be a pointer, a `bool`, a float, an integer or an enum. @@ -419,8 +474,19 @@ pub const builtins = [_]Builtin{ .signature = "@cmpxchgWeak(comptime T: type, ptr: *T, expected_value: T, new_value: T, success_order: AtomicOrder, fail_order: AtomicOrder) ?T", .snippet = "@cmpxchgWeak(${1:comptime T: type}, ${2:ptr: *T}, ${3:expected_value: T}, ${4:new_value: T}, ${5:success_order: AtomicOrder}, ${6:fail_order: AtomicOrder})", .documentation = - \\This function performs a weak atomic compare exchange operation. It's the equivalent of this code, except atomic:

{#syntax_block|zig|cmpxchgWeakButNotAtomic#} fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_value: T) ?T { const old_value = ptr.*; if (old_value == expected_value and usuallyTrueButSometimesFalse()) { ptr.* = new_value; return null; } else { return old_value; } } {#end_syntax_block#} + \\This function performs a weak atomic compare exchange operation. It's the equivalent of this code, except atomic: \\ + \\```zig + \\fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_value: T) ?T { + \\ const old_value = ptr.*; + \\ if (old_value == expected_value and usuallyTrueButSometimesFalse()) { + \\ ptr.* = new_value; + \\ return null; + \\ } else { + \\ return old_value; + \\ } + \\} + \\``` \\If you are using cmpxchg in a loop, the sporadic failure will be no problem, and `cmpxchgWeak` is the better choice, because it can be implemented more efficiently in machine instructions. However if you need a stronger guarantee, use [@cmpxchgStrong](https://ziglang.org/documentation/0.9.1/#cmpxchgStrong). \\ \\`T` must be a pointer, a `bool`, a float, an integer or an enum. @@ -462,24 +528,32 @@ pub const builtins = [_]Builtin{ \\ \\```zig \\const print = @import("std").debug.print; - \\ \\const num1 = blk: { \\ var val1: i32 = 99; \\ @compileLog("comptime val1 = ", val1); \\ val1 = val1 + 1; \\ break :blk val1; \\}; - \\ \\test "main" { \\ @compileLog("comptime in main"); - \\ \\ print("Runtime in main, num1 = {}.\n", .{num1}); \\} \\``` - \\ \\will output: \\ - \\If all `@compileLog` calls are removed or not encountered by analysis, the program compiles successfully and the generated executable prints:

{#code_begin|test|without_compileLog#} const print = @import("std").debug.print; const num1 = blk: { var val1: i32 = 99; val1 = val1 + 1; break :blk val1; }; test "main" { print("Runtime in main, num1 = {}.\n", .{num1}); }` + \\If all `@compileLog` calls are removed or not encountered by analysis, the program compiles successfully and the generated executable prints: + \\ + \\```zig + \\const print = @import("std").debug.print; + \\const num1 = blk: { + \\ var val1: i32 = 99; + \\ val1 = val1 + 1; + \\ break :blk val1; + \\}; + \\test "main" { + \\ print("Runtime in main, num1 = {}.\n", .{num1}); + \\} + \\``` , .arguments = &.{ "args: ...", @@ -512,7 +586,8 @@ pub const builtins = [_]Builtin{ .documentation = \\This function can only occur inside `@cImport`. \\ - \\This appends `#undef $name` to the `@cImport` temporary buffer. + \\This appends + \\`#undef $name`to the `@cImport` temporary buffer. , .arguments = &.{ "comptime name: []u8", @@ -524,9 +599,9 @@ pub const builtins = [_]Builtin{ .snippet = "@divExact(${1:numerator: T}, ${2:denominator: T})", .documentation = \\Exact division. Caller guarantees `denominator != 0` and `@divTrunc(numerator, denominator) * denominator == numerator`. - \\ - `@divExact(6, 3) == 2` - \\ - `@divExact(a, b) * b == a` \\ + \\ - `@divExact(6, 3) == 2` + \\ - `@divExact(a, b) * b == a` \\For a function that returns a possible error code, use `@import("std").math.divExact`. , .arguments = &.{ @@ -540,9 +615,9 @@ pub const builtins = [_]Builtin{ .snippet = "@divFloor(${1:numerator: T}, ${2:denominator: T})", .documentation = \\Floored division. Rounds toward negative infinity. For unsigned integers it is the same as `numerator / denominator`. Caller guarantees `denominator != 0` and `!(@typeInfo(T) == .Int and T.is_signed and numerator == std.math.minInt(T) and denominator == -1)`. - \\ - `@divFloor(-5, 3) == -2` - \\ - `(@divFloor(a, b) * b) + @mod(a, b) == a` \\ + \\ - `@divFloor(-5, 3) == -2` + \\ - `(@divFloor(a, b) * b) + @mod(a, b) == a` \\For a function that returns a possible error code, use `@import("std").math.divFloor`. , .arguments = &.{ @@ -556,9 +631,9 @@ pub const builtins = [_]Builtin{ .snippet = "@divTrunc(${1:numerator: T}, ${2:denominator: T})", .documentation = \\Truncated division. Rounds toward zero. For unsigned integers it is the same as `numerator / denominator`. Caller guarantees `denominator != 0` and `!(@typeInfo(T) == .Int and T.is_signed and numerator == std.math.minInt(T) and denominator == -1)`. - \\ - `@divTrunc(-5, 3) == -1` - \\ - `(@divTrunc(a, b) * b) + @rem(a, b) == a` \\ + \\ - `@divTrunc(-5, 3) == -1` + \\ - `(@divTrunc(a, b) * b) + @rem(a, b) == a` \\For a function that returns a possible error code, use `@import("std").math.divTrunc`. , .arguments = &.{ @@ -620,10 +695,10 @@ pub const builtins = [_]Builtin{ .snippet = "@errorToInt(${1:err: anytype})", .documentation = \\Supports the following types: - \\ - [The Global Error Set](https://ziglang.org/documentation/0.9.1/#The-Global-Error-Set) - \\ - [Error Set Type](https://ziglang.org/documentation/0.9.1/#Error-Set-Type) - \\ - [Error Union Type](https://ziglang.org/documentation/0.9.1/#Error-Union-Type) \\ + \\ - [The Global Error Set](https://ziglang.org/documentation/0.9.1/#The-Global-Error-Set) + \\ - [Error Set Type](https://ziglang.org/documentation/0.9.1/#Error-Set-Type) + \\ - [Error Union Type](https://ziglang.org/documentation/0.9.1/#Error-Union-Type) \\Converts an error to the integer representation of an error. \\ \\It is generally recommended to avoid this cast, as the integer representation of an error is not stable across source code changes. @@ -651,37 +726,28 @@ pub const builtins = [_]Builtin{ .documentation = \\Creates a symbol in the output object file. \\ - \\`declaration` must be one of two things: - \\ - An identifier (`x`) identifying a [function](https://ziglang.org/documentation/0.9.1/#Functions) or a [variable](https://ziglang.org/documentation/0.9.1/#Container-Level-Variables). - \\ - Field access (`x.y`) looking up a [function](https://ziglang.org/documentation/0.9.1/#Functions) or a [variable](https://ziglang.org/documentation/0.9.1/#Container-Level-Variables). + \\`declaration`must be one of two things: \\ - \\This builtin can be called from a [comptime](https://ziglang.org/documentation/0.9.1/#comptime) block to conditionally export symbols. When `declaration` is a function with the C calling convention and `options.linkage` is `Strong`, this is equivalent to the `export` keyword used on a function: + \\ - An identifier (`x`) identifying a [function](https://ziglang.org/documentation/0.9.1/#Functions) or a [variable](https://ziglang.org/documentation/0.9.1/#Container-Level-Variables). + \\ - Field access (`x.y`) looking up a [function](https://ziglang.org/documentation/0.9.1/#Functions) or a [variable](https://ziglang.org/documentation/0.9.1/#Container-Level-Variables). + \\This builtin can be called from a [comptime](https://ziglang.org/documentation/0.9.1/#comptime) block to conditionally export symbols. When + \\`declaration`is a function with the C calling convention and `options.linkage` is `Strong`, this is equivalent to the `export` keyword used on a function: \\ \\```zig \\comptime { \\ @export(internalName, .{ .name = "foo", .linkage = .Strong }); \\} - \\ \\fn internalName() callconv(.C) void {} \\``` - \\ \\This is equivalent to: \\ - \\```zig - \\export fn foo() void {} - \\``` - \\ + \\`export fn foo() void {}` \\Note that even when using `export`, the `@"foo"` syntax for [identifiers](https://ziglang.org/documentation/0.9.1/#Identifiers) can be used to choose any string for the symbol name: \\ - \\```zig - \\export fn @"A function name that is a complete sentence."() void {} - \\``` - \\ + \\`export fn @"A function name that is a complete sentence."() void {}` \\When looking at the resulting object, you can see the symbol is used verbatim: \\ - \\```zig - \\00000000000001f0 T A function name that is a complete sentence. - \\``` + \\`00000000000001f0 T A function name that is a complete sentence.` , .arguments = &.{ "declaration", @@ -718,7 +784,30 @@ pub const builtins = [_]Builtin{ .signature = "@field(lhs: anytype, comptime field_name: []const u8) (field)", .snippet = "@field(${1:lhs: anytype}, ${2:comptime field_name: []const u8})", .documentation = - \\Performs field access by a compile-time string. Works on both fields and declarations.

{#code_begin|test|field_decl_access_by_string#} const std = @import("std"); const Point = struct { x: u32, y: u32, pub var z: u32 = 1; }; test "field access by string" { const expect = std.testing.expect; var p = Point{ .x = 0, .y = 0 }; @field(p, "x") = 4; @field(p, "y") = @field(p, "x") + 1; try expect(@field(p, "x") == 4); try expect(@field(p, "y") == 5); } test "decl access by string" { const expect = std.testing.expect; try expect(@field(Point, "z") == 1); @field(Point, "z") = 2; try expect(@field(Point, "z") == 2); }` + \\Performs field access by a compile-time string. Works on both fields and declarations. + \\ + \\```zig + \\const std = @import("std"); + \\const Point = struct { + \\ x: u32, + \\ y: u32, + \\ pub var z: u32 = 1; + \\}; + \\test "field access by string" { + \\ const expect = std.testing.expect; + \\ var p = Point{ .x = 0, .y = 0 }; + \\ @field(p, "x") = 4; + \\ @field(p, "y") = @field(p, "x") + 1; + \\ try expect(@field(p, "x") == 4); + \\ try expect(@field(p, "y") == 5); + \\} + \\test "decl access by string" { + \\ const expect = std.testing.expect; + \\ try expect(@field(Point, "z") == 1); + \\ @field(Point, "z") = 2; + \\ try expect(@field(Point, "z") == 2); + \\} + \\``` , .arguments = &.{ "lhs: anytype", @@ -727,7 +816,7 @@ pub const builtins = [_]Builtin{ }, .{ .name = "@fieldParentPtr", - .signature = "@fieldParentPtr(comptime ParentType: type, comptime field_name: []const u8, field_ptr: *T) *ParentType", + .signature = "@fieldParentPtr(comptime ParentType: type, comptime field_name: []const u8, field_ptr: *T) *ParentType", .snippet = "@fieldParentPtr(${1:comptime ParentType: type}, ${2:comptime field_name: []const u8}, ${3:field_ptr: *T})", .documentation = \\Given a pointer to a field, returns the base pointer of a struct. @@ -782,7 +871,18 @@ pub const builtins = [_]Builtin{ .documentation = \\This function returns the frame type of a function. This works for [Async Functions](https://ziglang.org/documentation/0.9.1/#Async-Functions) as well as any function without a specific calling convention. \\ - \\This type is suitable to be used as the return type of [async](https://ziglang.org/documentation/0.9.1/#Async-and-Await) which allows one to, for example, heap-allocate an async function frame:

{#code_begin|test|heap_allocated_frame#} const std = @import("std"); test "heap allocated frame" { const frame = try std.heap.page_allocator.create(@Frame(func)); frame.* = async func(); } fn func() void { suspend {} }` + \\This type is suitable to be used as the return type of [async](https://ziglang.org/documentation/0.9.1/#Async-and-Await) which allows one to, for example, heap-allocate an async function frame: + \\ + \\```zig + \\const std = @import("std"); + \\test "heap allocated frame" { + \\ const frame = try std.heap.page_allocator.create(@Frame(func)); + \\ frame.* = async func(); + \\} + \\fn func() void { + \\ suspend {} + \\} + \\``` , .arguments = &.{ "func: anytype", @@ -817,7 +917,27 @@ pub const builtins = [_]Builtin{ .signature = "@hasDecl(comptime Container: type, comptime name: []const u8) bool", .snippet = "@hasDecl(${1:comptime Container: type}, ${2:comptime name: []const u8})", .documentation = - \\Returns whether or not a [struct](https://ziglang.org/documentation/0.9.1/#struct), [enum](https://ziglang.org/documentation/0.9.1/#enum), or [union](https://ziglang.org/documentation/0.9.1/#union) has a declaration matching `name`.

{#code_begin|test|hasDecl#} const std = @import("std"); const expect = std.testing.expect; const Foo = struct { nope: i32, pub var blah = "xxx"; const hi = 1; }; test "@hasDecl" { try expect(@hasDecl(Foo, "blah")); // Even though `hi` is private, @hasDecl returns true because this test is // in the same file scope as Foo. It would return false if Foo was declared // in a different file. try expect(@hasDecl(Foo, "hi")); // @hasDecl is for declarations; not fields. try expect(!@hasDecl(Foo, "nope")); try expect(!@hasDecl(Foo, "nope1234")); }` + \\Returns whether or not a [struct](https://ziglang.org/documentation/0.9.1/#struct), [enum](https://ziglang.org/documentation/0.9.1/#enum), or [union](https://ziglang.org/documentation/0.9.1/#union) has a declaration matching `name`. + \\ + \\```zig + \\const std = @import("std"); + \\const expect = std.testing.expect; + \\const Foo = struct { + \\ nope: i32, + \\ pub var blah = "xxx"; + \\ const hi = 1; + \\}; + \\test "@hasDecl" { + \\ try expect(@hasDecl(Foo, "blah")); + \\ // Even though `hi` is private, @hasDecl returns true because this test is + \\ // in the same file scope as Foo. It would return false if Foo was declared + \\ // in a different file. + \\ try expect(@hasDecl(Foo, "hi")); + \\ // @hasDecl is for declarations; not fields. + \\ try expect(!@hasDecl(Foo, "nope")); + \\ try expect(!@hasDecl(Foo, "nope1234")); + \\} + \\``` , .arguments = &.{ "comptime Container: type", @@ -854,9 +974,11 @@ pub const builtins = [_]Builtin{ \\`path` can be a relative path or it can be the name of a package. If it is a relative path, it is relative to the file that contains the `@import` function call. \\ \\The following packages are always available: - \\ - `@import("std")` - Zig Standard Library - \\ - `@import("builtin")` - Target-specific information The command `zig build-exe --show-builtin` outputs the source to stdout for reference. - \\ - `@import("root")` - Points to the root source file This is usually `src/main.zig` but it depends on what file is chosen to be built. + \\ + \\ - `@import("std")` - Zig Standard Library + \\ - `@import("builtin")` - Target-specific information The command + \\`zig build-exe --show-builtin`outputs the source to stdout for reference. + \\ - `@import("root")` - Points to the root source file This is usually `src/main.zig` but it depends on what file is chosen to be built. , .arguments = &.{ "comptime path: []u8", @@ -876,7 +998,6 @@ pub const builtins = [_]Builtin{ \\ _ = b; \\} \\``` - \\ \\To truncate the significant bits of a number out of range of the destination type, use [@truncate](https://ziglang.org/documentation/0.9.1/#truncate). \\ \\If `T` is `comptime_int`, then this is semantically equivalent to [Type Coercion](https://ziglang.org/documentation/0.9.1/#Type-Coercion). @@ -903,7 +1024,7 @@ pub const builtins = [_]Builtin{ .{ .name = "@intToError", .signature = "@intToError(value: std.meta.Int(.unsigned, @sizeOf(anyerror) * 8)) anyerror", - .snippet = "@intToError(${1:value: std.meta.Int(.unsigned, @sizeOf(anyerror) * 8)})", + .snippet = "@intToError(${1:value: std.meta.Int(.unsigned, @sizeOf(anyerror) * 8})", .documentation = \\Converts from the integer representation of an error into [The Global Error Set](https://ziglang.org/documentation/0.9.1/#The-Global-Error-Set) type. \\ @@ -912,7 +1033,7 @@ pub const builtins = [_]Builtin{ \\Attempting to convert an integer that does not correspond to any error results in safety-protected [Undefined Behavior](https://ziglang.org/documentation/0.9.1/#Undefined-Behavior). , .arguments = &.{ - "value: std.meta.Int(.unsigned, @sizeOf(anyerror) * 8)", + "value: std.meta.Int(.unsigned, @sizeOf(anyerror) * 8", }, }, .{ @@ -964,10 +1085,7 @@ pub const builtins = [_]Builtin{ \\ \\This function is a low level intrinsic with no safety mechanisms. Most code should not use this function, instead using something like this: \\ - \\```zig - \\for (source[0..byte_count]) |b, i| dest[i] = b; - \\``` - \\ + \\`for (source[0..byte_count]) |b, i| dest[i] = b;` \\The optimizer is intelligent enough to turn the above snippet into a memcpy. \\ \\There is also a standard library function for this: @@ -992,10 +1110,7 @@ pub const builtins = [_]Builtin{ \\ \\This function is a low level intrinsic with no safety mechanisms. Most code should not use this function, instead using something like this: \\ - \\```zig - \\for (dest[0..byte_count]) |*b| b.* = c; - \\``` - \\ + \\`for (dest[0..byte_count]) |*b| b.* = c;` \\The optimizer is intelligent enough to turn the above snippet into a memset. \\ \\There is also a standard library function for this: @@ -1045,7 +1160,19 @@ pub const builtins = [_]Builtin{ .documentation = \\This function increases the size of the Wasm memory identified by `index` by `delta` in units of unsigned number of Wasm pages. Note that each Wasm page is 64KB in size. On success, returns previous memory size; on failure, if the allocation fails, returns -1. \\ - \\This function is a low level intrinsic with no safety mechanisms usually useful for allocator designers targeting Wasm. So unless you are writing a new allocator from scratch, you should use something like `@import("std").heap.WasmPageAllocator`.

{#code_begin|test|wasmMemoryGrow#} const std = @import("std"); const native_arch = @import("builtin").target.cpu.arch; const expect = std.testing.expect; test "@wasmMemoryGrow" { if (native_arch != .wasm32) return error.SkipZigTest; var prev = @wasmMemorySize(0); try expect(prev == @wasmMemoryGrow(0, 1)); try expect(prev + 1 == @wasmMemorySize(0)); }` + \\This function is a low level intrinsic with no safety mechanisms usually useful for allocator designers targeting Wasm. So unless you are writing a new allocator from scratch, you should use something like `@import("std").heap.WasmPageAllocator`. + \\ + \\```zig + \\const std = @import("std"); + \\const native_arch = @import("builtin").target.cpu.arch; + \\const expect = std.testing.expect; + \\test "@wasmMemoryGrow" { + \\ if (native_arch != .wasm32) return error.SkipZigTest; + \\ var prev = @wasmMemorySize(0); + \\ try expect(prev == @wasmMemoryGrow(0, 1)); + \\ try expect(prev + 1 == @wasmMemorySize(0)); + \\} + \\``` , .arguments = &.{ "index: u32", @@ -1058,9 +1185,9 @@ pub const builtins = [_]Builtin{ .snippet = "@mod(${1:numerator: T}, ${2:denominator: T})", .documentation = \\Modulus division. For unsigned integers this is the same as `numerator % denominator`. Caller guarantees `denominator > 0`, otherwise the operation will result in a [Remainder Division by Zero](https://ziglang.org/documentation/0.9.1/#Remainder-Division-by-Zero) when runtime safety checks are enabled. - \\ - `@mod(-5, 3) == 1` - \\ - `(@divFloor(a, b) * b) + @mod(a, b) == a` \\ + \\ - `@mod(-5, 3) == 1` + \\ - `(@divFloor(a, b) * b) + @mod(a, b) == a` \\For a function that returns an error code, see `@import("std").math.mod`. , .arguments = &.{ @@ -1090,8 +1217,9 @@ pub const builtins = [_]Builtin{ \\Invokes the panic handler function. By default the panic handler function calls the public `panic` function exposed in the root source file, or if there is not one specified, the `std.builtin.default_panic` function from `std/builtin.zig`. \\ \\Generally it is better to use `@import("std").debug.panic`. However, `@panic` can be useful for 2 scenarios: - \\ - From library code, calling the programmer's panic function if they exposed one in the root source file. - \\ - When mixing C and Zig code, calling the canonical panic implementation across multiple .o files. + \\ + \\ - From library code, calling the programmer's panic function if they exposed one in the root source file. + \\ - When mixing C and Zig code, calling the canonical panic implementation across multiple .o files. , .arguments = &.{ "message: []const u8", @@ -1124,7 +1252,32 @@ pub const builtins = [_]Builtin{ \\ \\The `ptr` argument may be any pointer type and determines the memory address to prefetch. This function does not dereference the pointer, it is perfectly legal to pass a pointer to invalid memory to this function and no illegal behavior will result. \\ - \\The `options` argument is the following struct:

{#code_begin|syntax|builtin#} /// This data structure is used by the Zig language code generation and /// therefore must be kept in sync with the compiler implementation. pub const PrefetchOptions = struct { /// Whether the prefetch should prepare for a read or a write. rw: Rw = .read, /// 0 means no temporal locality. That is, the data can be immediately /// dropped from the cache after it is accessed. /// /// 3 means high temporal locality. That is, the data should be kept in /// the cache as it is likely to be accessed again soon. locality: u2 = 3, /// The cache that the prefetch should be preformed on. cache: Cache = .data, pub const Rw = enum { read, write, }; pub const Cache = enum { instruction, data, }; };` + \\The `options` argument is the following struct: + \\ + \\```zig + \\/// This data structure is used by the Zig language code generation and + \\/// therefore must be kept in sync with the compiler implementation. + \\pub const PrefetchOptions = struct { + \\ /// Whether the prefetch should prepare for a read or a write. + \\ rw: Rw = .read, + \\ /// 0 means no temporal locality. That is, the data can be immediately + \\ /// dropped from the cache after it is accessed. + \\ /// + \\ /// 3 means high temporal locality. That is, the data should be kept in + \\ /// the cache as it is likely to be accessed again soon. + \\ locality: u2 = 3, + \\ /// The cache that the prefetch should be preformed on. + \\ cache: Cache = .data, + \\ pub const Rw = enum { + \\ read, + \\ write, + \\ }; + \\ pub const Cache = enum { + \\ instruction, + \\ data, + \\ }; + \\}; + \\``` , .arguments = &.{ "ptr: anytype", @@ -1151,11 +1304,11 @@ pub const builtins = [_]Builtin{ .snippet = "@ptrToInt(${1:value: anytype})", .documentation = \\Converts `value` to a `usize` which is the address of the pointer. `value` can be one of these types: - \\ - `*T` - \\ - `?*T` - \\ - `fn()` - \\ - `?fn()` \\ + \\ - `*T` + \\ - `?*T` + \\ - `fn()` + \\ - `?fn()` \\To convert the other way, use [@intToPtr](https://ziglang.org/documentation/0.9.1/#intToPtr) , .arguments = &.{ @@ -1168,9 +1321,9 @@ pub const builtins = [_]Builtin{ .snippet = "@rem(${1:numerator: T}, ${2:denominator: T})", .documentation = \\Remainder division. For unsigned integers this is the same as `numerator % denominator`. Caller guarantees `denominator > 0`, otherwise the operation will result in a [Remainder Division by Zero](https://ziglang.org/documentation/0.9.1/#Remainder-Division-by-Zero) when runtime safety checks are enabled. - \\ - `@rem(-5, 3) == -2` - \\ - `(@divTrunc(a, b) * b) + @rem(a, b) == a` \\ + \\ - `@rem(-5, 3) == -2` + \\ - `(@divTrunc(a, b) * b) + @rem(a, b) == a` \\For a function that returns an error code, see `@import("std").math.rem`. , .arguments = &.{ @@ -1238,16 +1391,16 @@ pub const builtins = [_]Builtin{ \\ \\Example: \\ - \\```zig - \\test "foo" { - \\ comptime { - \\ var i = 0; - \\ while (i < 1001) : (i += 1) {} + \\1001) : (i += 1) {} \\ } \\} \\``` + \\Now we use `@setEvalBranchQuota`: \\ - \\Now we use `@setEvalBranchQuota`:

{#code_begin|test|setEvalBranchQuota#} test "foo" { comptime { @setEvalBranchQuota(1001); var i = 0; while (i < 1001) : (i += 1) {} } }` + \\1001) : (i += 1) {} + \\ } + \\} + \\``` , .arguments = &.{ "comptime new_quota: u32", @@ -1266,16 +1419,16 @@ pub const builtins = [_]Builtin{ \\ Optimized, \\}; \\``` - \\ - \\ - `Strict` (default) - Floating point operations follow strict IEEE compliance. - \\ - `Optimized` - Floating point operations may do all of the following:
    - \\ - Assume the arguments and result are not NaN. Optimizations are required to retain defined behavior over NaNs, but the value of the result is undefined. - \\ - Assume the arguments and result are not +/-Inf. Optimizations are required to retain defined behavior over +/-Inf, but the value of the result is undefined. - \\ - Treat the sign of a zero argument or result as insignificant. - \\ - Use the reciprocal of an argument rather than perform division. - \\ - Perform floating-point contraction (e.g. fusing a multiply followed by an addition into a fused multiply-and-add). - \\ - Perform algebraically equivalent transformations that may change results in floating point (e.g. reassociate). This is equivalent to `-ffast-math` in GCC.
- \\ + \\ - `Strict` (default) - Floating point operations follow strict IEEE compliance. + \\ - `Optimized` - Floating point operations may do all of the following: + \\ - Assume the arguments and result are not NaN. Optimizations are required to retain defined behavior over NaNs, but the value of the result is undefined. + \\ - Assume the arguments and result are not +/-Inf. Optimizations are required to retain defined behavior over +/-Inf, but the value of the result is undefined. + \\ - Treat the sign of a zero argument or result as insignificant. + \\ - Use the reciprocal of an argument rather than perform division. + \\ - Perform floating-point contraction (e.g. fusing a multiply followed by an addition into a fused multiply-and-add). + \\ - Perform algebraically equivalent transformations that may change results in floating point (e.g. reassociate). + \\This is equivalent to + \\`-ffast-math`in GCC. \\The floating point mode is inherited by child scopes, and can be overridden in any scope. You can set the floating point mode in a struct or module scope by using a comptime block. , .arguments = &.{ @@ -1301,7 +1454,6 @@ pub const builtins = [_]Builtin{ \\ @setRuntimeSafety(true); \\ var x: u8 = 255; \\ x += 1; - \\ \\ { \\ // The value can be overridden at any scope. So here integer overflow \\ // would not be caught in any build mode. @@ -1312,8 +1464,9 @@ pub const builtins = [_]Builtin{ \\ } \\} \\``` - \\ - \\Note: it is [planned](https://github.com/ziglang/zig/issues/978) to replace `@setRuntimeSafety` with `@optimizeFor` + \\Note: it is + \\[planned](https://github.com/ziglang/zig/issues/978)to replace `@setRuntimeSafety` with + \\`@optimizeFor` , .arguments = &.{ "comptime safety_on: bool", @@ -1324,7 +1477,7 @@ pub const builtins = [_]Builtin{ .signature = "@shlExact(value: T, shift_amt: Log2T) T", .snippet = "@shlExact(${1:value: T}, ${2:shift_amt: Log2T})", .documentation = - \\Performs the left shift operation (`<<`). For unsigned integers, the result is [undefined](https://ziglang.org/documentation/0.9.1/#undefined) if any 1 bits are shifted out. For signed integers, the result is [undefined](https://ziglang.org/documentation/0.9.1/#undefined) if any bits that disagree with the resultant sign bit are shifted out. + \\`). For unsigned integers, the result is [undefined](https://ziglang.org/documentation/0.9.1/#undefined) if any 1 bits are shifted out. For signed integers, the result is [undefined](https://ziglang.org/documentation/0.9.1/#undefined) if any bits that disagree with the resultant sign bit are shifted out. \\ \\The type of `shift_amt` is an unsigned integer with `log2(T.bit_count)` bits. This is because `shift_amt >= T.bit_count` is undefined behavior. , @@ -1338,7 +1491,7 @@ pub const builtins = [_]Builtin{ .signature = "@shlWithOverflow(comptime T: type, a: T, shift_amt: Log2T, result: *T) bool", .snippet = "@shlWithOverflow(${1:comptime T: type}, ${2:a: T}, ${3:shift_amt: Log2T}, ${4:result: *T})", .documentation = - \\Performs `result.* = a << b`. If overflow or underflow occurs, stores the overflowed bits in `result` and returns `true`. If no overflow or underflow occurs, returns `false`. + \\b`. If overflow or underflow occurs, stores the overflowed bits in `result` and returns `true`. If no overflow or underflow occurs, returns `false`. \\ \\The type of `shift_amt` is an unsigned integer with `log2(T.bit_count)` bits. This is because `shift_amt >= T.bit_count` is undefined behavior. , @@ -1378,7 +1531,26 @@ pub const builtins = [_]Builtin{ \\ \\If `a` or `b` is `undefined`, it is equivalent to a vector of all `undefined` with the same length as the other vector. If both vectors are `undefined`, `@shuffle` returns a vector with all elements `undefined`. \\ - \\`E` must be an [integer](https://ziglang.org/documentation/0.9.1/#Integers), [float](https://ziglang.org/documentation/0.9.1/#Floats), [pointer](https://ziglang.org/documentation/0.9.1/#Pointers), or `bool`. The mask may be any vector length, and its length determines the result length.

{#code_begin|test|vector_shuffle#} const std = @import("std"); const Vector = std.meta.Vector; const expect = std.testing.expect; test "vector @shuffle" { const a: Vector(7, u8) = [_]u8{ 'o', 'l', 'h', 'e', 'r', 'z', 'w' }; const b: Vector(4, u8) = [_]u8{ 'w', 'd', '!', 'x' }; // To shuffle within a single vector, pass undefined as the second argument. // Notice that we can re-order, duplicate, or omit elements of the input vector const mask1: Vector(5, i32) = [_]i32{ 2, 3, 1, 1, 0 }; const res1: Vector(5, u8) = @shuffle(u8, a, undefined, mask1); try expect(std.mem.eql(u8, &@as([5]u8, res1), "hello")); // Combining two vectors const mask2: Vector(6, i32) = [_]i32{ -1, 0, 4, 1, -2, -3 }; const res2: Vector(6, u8) = @shuffle(u8, a, b, mask2); try expect(std.mem.eql(u8, &@as([6]u8, res2), "world!")); }` + \\`E` must be an [integer](https://ziglang.org/documentation/0.9.1/#Integers), [float](https://ziglang.org/documentation/0.9.1/#Floats), [pointer](https://ziglang.org/documentation/0.9.1/#Pointers), or `bool`. The mask may be any vector length, and its length determines the result length. + \\ + \\```zig + \\const std = @import("std"); + \\const Vector = std.meta.Vector; + \\const expect = std.testing.expect; + \\test "vector @shuffle" { + \\ const a: Vector(7, u8) = [_]u8{ 'o', 'l', 'h', 'e', 'r', 'z', 'w' }; + \\ const b: Vector(4, u8) = [_]u8{ 'w', 'd', '!', 'x' }; + \\ // To shuffle within a single vector, pass undefined as the second argument. + \\ // Notice that we can re-order, duplicate, or omit elements of the input vector + \\ const mask1: Vector(5, i32) = [_]i32{ 2, 3, 1, 1, 0 }; + \\ const res1: Vector(5, u8) = @shuffle(u8, a, undefined, mask1); + \\ try expect(std.mem.eql(u8, &@as([5]u8, res1), "hello")); + \\ // Combining two vectors + \\ const mask2: Vector(6, i32) = [_]i32{ -1, 0, 4, 1, -2, -3 }; + \\ const res2: Vector(6, u8) = @shuffle(u8, a, b, mask2); + \\ try expect(std.mem.eql(u8, &@as([6]u8, res2), "world!")); + \\} + \\``` , .arguments = &.{ "comptime E: type", @@ -1407,8 +1579,18 @@ pub const builtins = [_]Builtin{ .signature = "@splat(comptime len: u32, scalar: anytype) std.meta.Vector(len, @TypeOf(scalar))", .snippet = "@splat(${1:comptime len: u32}, ${2:scalar: anytype})", .documentation = - \\Produces a vector of length `len` where each element is the value `scalar`:

{#code_begin|test|vector_splat#} const std = @import("std"); const expect = std.testing.expect; test "vector @splat" { const scalar: u32 = 5; const result = @splat(4, scalar); comptime try expect(@TypeOf(result) == std.meta.Vector(4, u32)); try expect(std.mem.eql(u32, &@as([4]u32, result), &[_]u32{ 5, 5, 5, 5 })); }` + \\Produces a vector of length `len` where each element is the value `scalar`: \\ + \\```zig + \\const std = @import("std"); + \\const expect = std.testing.expect; + \\test "vector @splat" { + \\ const scalar: u32 = 5; + \\ const result = @splat(4, scalar); + \\ comptime try expect(@TypeOf(result) == std.meta.Vector(4, u32)); + \\ try expect(std.mem.eql(u32, &@as([4]u32, result), &[_]u32{ 5, 5, 5, 5 })); + \\} + \\``` \\`scalar` must be an [integer](https://ziglang.org/documentation/0.9.1/#Integers), [bool](https://ziglang.org/documentation/0.9.1/#Primitive-Types), [float](https://ziglang.org/documentation/0.9.1/#Floats), or [pointer](https://ziglang.org/documentation/0.9.1/#Pointers). , .arguments = &.{ @@ -1424,11 +1606,25 @@ pub const builtins = [_]Builtin{ \\Transforms a [vector](https://ziglang.org/documentation/0.9.1/#Vectors) into a scalar value by performing a sequential horizontal reduction of its elements using the specified operator `op`. \\ \\Not every operator is available for every vector element type: - \\ - `.And`, `.Or`, `.Xor` are available for `bool` vectors, - \\ - `.Min`, `.Max`, `.Add`, `.Mul` are available for [floating point](https://ziglang.org/documentation/0.9.1/#Floats) vectors, - \\ - Every operator is available for [integer](https://ziglang.org/documentation/0.9.1/#Integers) vectors. \\ - \\Note that `.Add` and `.Mul` reductions on integral types are wrapping; when applied on floating point types the operation associativity is preserved, unless the float mode is set to `Optimized`.

{#code_begin|test|vector_reduce#} const std = @import("std"); const expect = std.testing.expect; test "vector @reduce" { const value: std.meta.Vector(4, i32) = [_]i32{ 1, -1, 1, -1 }; const result = value > @splat(4, @as(i32, 0)); // result is { true, false, true, false }; comptime try expect(@TypeOf(result) == std.meta.Vector(4, bool)); const is_all_true = @reduce(.And, result); comptime try expect(@TypeOf(is_all_true) == bool); try expect(is_all_true == false); }` + \\ - `.And`, `.Or`, `.Xor` are available for `bool` vectors, + \\ - `.Min`, `.Max`, `.Add`, `.Mul` are available for [floating point](https://ziglang.org/documentation/0.9.1/#Floats) vectors, + \\ - Every operator is available for [integer](https://ziglang.org/documentation/0.9.1/#Integers) vectors. + \\Note that `.Add` and `.Mul` reductions on integral types are wrapping; when applied on floating point types the operation associativity is preserved, unless the float mode is set to `Optimized`. + \\ + \\```zig + \\const std = @import("std"); + \\const expect = std.testing.expect; + \\test "vector @reduce" { + \\ const value: std.meta.Vector(4, i32) = [_]i32{ 1, -1, 1, -1 }; + \\ const result = value > @splat(4, @as(i32, 0)); + \\ // result is { true, false, true, false }; + \\ comptime try expect(@TypeOf(result) == std.meta.Vector(4, bool)); + \\ const is_all_true = @reduce(.And, result); + \\ comptime try expect(@TypeOf(is_all_true) == bool); + \\ try expect(is_all_true == false); + \\} + \\``` , .arguments = &.{ "comptime op: std.builtin.ReduceOp", @@ -1440,7 +1636,22 @@ pub const builtins = [_]Builtin{ .signature = "@src() std.builtin.SourceLocation", .snippet = "@src()", .documentation = - \\Returns a `SourceLocation` struct representing the function's name and location in the source code. This must be called in a function.

{#code_begin|test|source_location#} const std = @import("std"); const expect = std.testing.expect; test "@src" { try doTheTest(); } fn doTheTest() !void { const src = @src(); try expect(src.line == 9); try expect(src.column == 17); try expect(std.mem.endsWith(u8, src.fn_name, "doTheTest")); try expect(std.mem.endsWith(u8, src.file, "source_location.zig")); }` + \\Returns a `SourceLocation` struct representing the function's name and location in the source code. This must be called in a function. + \\ + \\```zig + \\const std = @import("std"); + \\const expect = std.testing.expect; + \\test "@src" { + \\ try doTheTest(); + \\} + \\fn doTheTest() !void { + \\ const src = @src(); + \\ try expect(src.line == 9); + \\ try expect(src.column == 17); + \\ try expect(std.mem.endsWith(u8, src.fn_name, "doTheTest")); + \\ try expect(std.mem.endsWith(u8, src.file, "source_location.zig")); + \\} + \\``` , .arguments = &.{}, }, @@ -1451,7 +1662,8 @@ pub const builtins = [_]Builtin{ .documentation = \\Performs the square root of a floating point number. Uses a dedicated hardware instruction when available. \\ - \\Supports [Floats](https://ziglang.org/documentation/0.9.1/#Floats) and [Vectors](https://ziglang.org/documentation/0.9.1/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). + \\Supports [Floats](https://ziglang.org/documentation/0.9.1/#Floats) and [Vectors](https://ziglang.org/documentation/0.9.1/#Vectors) of floats, with the caveat that + \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). , .arguments = &.{ "value: anytype", @@ -1464,7 +1676,8 @@ pub const builtins = [_]Builtin{ .documentation = \\Sine trigonometric function on a floating point number. Uses a dedicated hardware instruction when available. \\ - \\Supports [Floats](https://ziglang.org/documentation/0.9.1/#Floats) and [Vectors](https://ziglang.org/documentation/0.9.1/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). + \\Supports [Floats](https://ziglang.org/documentation/0.9.1/#Floats) and [Vectors](https://ziglang.org/documentation/0.9.1/#Vectors) of floats, with the caveat that + \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). , .arguments = &.{ "value: anytype", @@ -1477,7 +1690,8 @@ pub const builtins = [_]Builtin{ .documentation = \\Cosine trigonometric function on a floating point number. Uses a dedicated hardware instruction when available. \\ - \\Supports [Floats](https://ziglang.org/documentation/0.9.1/#Floats) and [Vectors](https://ziglang.org/documentation/0.9.1/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). + \\Supports [Floats](https://ziglang.org/documentation/0.9.1/#Floats) and [Vectors](https://ziglang.org/documentation/0.9.1/#Vectors) of floats, with the caveat that + \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). , .arguments = &.{ "value: anytype", @@ -1490,7 +1704,8 @@ pub const builtins = [_]Builtin{ .documentation = \\Base-e exponential function on a floating point number. Uses a dedicated hardware instruction when available. \\ - \\Supports [Floats](https://ziglang.org/documentation/0.9.1/#Floats) and [Vectors](https://ziglang.org/documentation/0.9.1/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). + \\Supports [Floats](https://ziglang.org/documentation/0.9.1/#Floats) and [Vectors](https://ziglang.org/documentation/0.9.1/#Vectors) of floats, with the caveat that + \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). , .arguments = &.{ "value: anytype", @@ -1503,7 +1718,8 @@ pub const builtins = [_]Builtin{ .documentation = \\Base-2 exponential function on a floating point number. Uses a dedicated hardware instruction when available. \\ - \\Supports [Floats](https://ziglang.org/documentation/0.9.1/#Floats) and [Vectors](https://ziglang.org/documentation/0.9.1/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). + \\Supports [Floats](https://ziglang.org/documentation/0.9.1/#Floats) and [Vectors](https://ziglang.org/documentation/0.9.1/#Vectors) of floats, with the caveat that + \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). , .arguments = &.{ "value: anytype", @@ -1516,7 +1732,8 @@ pub const builtins = [_]Builtin{ .documentation = \\Returns the natural logarithm of a floating point number. Uses a dedicated hardware instruction when available. \\ - \\Supports [Floats](https://ziglang.org/documentation/0.9.1/#Floats) and [Vectors](https://ziglang.org/documentation/0.9.1/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). + \\Supports [Floats](https://ziglang.org/documentation/0.9.1/#Floats) and [Vectors](https://ziglang.org/documentation/0.9.1/#Vectors) of floats, with the caveat that + \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). , .arguments = &.{ "value: anytype", @@ -1529,7 +1746,8 @@ pub const builtins = [_]Builtin{ .documentation = \\Returns the logarithm to the base 2 of a floating point number. Uses a dedicated hardware instruction when available. \\ - \\Supports [Floats](https://ziglang.org/documentation/0.9.1/#Floats) and [Vectors](https://ziglang.org/documentation/0.9.1/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). + \\Supports [Floats](https://ziglang.org/documentation/0.9.1/#Floats) and [Vectors](https://ziglang.org/documentation/0.9.1/#Vectors) of floats, with the caveat that + \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). , .arguments = &.{ "value: anytype", @@ -1542,7 +1760,8 @@ pub const builtins = [_]Builtin{ .documentation = \\Returns the logarithm to the base 10 of a floating point number. Uses a dedicated hardware instruction when available. \\ - \\Supports [Floats](https://ziglang.org/documentation/0.9.1/#Floats) and [Vectors](https://ziglang.org/documentation/0.9.1/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). + \\Supports [Floats](https://ziglang.org/documentation/0.9.1/#Floats) and [Vectors](https://ziglang.org/documentation/0.9.1/#Vectors) of floats, with the caveat that + \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). , .arguments = &.{ "value: anytype", @@ -1555,7 +1774,8 @@ pub const builtins = [_]Builtin{ .documentation = \\Returns the absolute value of a floating point number. Uses a dedicated hardware instruction when available. \\ - \\Supports [Floats](https://ziglang.org/documentation/0.9.1/#Floats) and [Vectors](https://ziglang.org/documentation/0.9.1/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). + \\Supports [Floats](https://ziglang.org/documentation/0.9.1/#Floats) and [Vectors](https://ziglang.org/documentation/0.9.1/#Vectors) of floats, with the caveat that + \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). , .arguments = &.{ "value: anytype", @@ -1568,7 +1788,8 @@ pub const builtins = [_]Builtin{ .documentation = \\Returns the largest integral value not greater than the given floating point number. Uses a dedicated hardware instruction when available. \\ - \\Supports [Floats](https://ziglang.org/documentation/0.9.1/#Floats) and [Vectors](https://ziglang.org/documentation/0.9.1/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). + \\Supports [Floats](https://ziglang.org/documentation/0.9.1/#Floats) and [Vectors](https://ziglang.org/documentation/0.9.1/#Vectors) of floats, with the caveat that + \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). , .arguments = &.{ "value: anytype", @@ -1581,7 +1802,8 @@ pub const builtins = [_]Builtin{ .documentation = \\Returns the smallest integral value not less than the given floating point number. Uses a dedicated hardware instruction when available. \\ - \\Supports [Floats](https://ziglang.org/documentation/0.9.1/#Floats) and [Vectors](https://ziglang.org/documentation/0.9.1/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). + \\Supports [Floats](https://ziglang.org/documentation/0.9.1/#Floats) and [Vectors](https://ziglang.org/documentation/0.9.1/#Vectors) of floats, with the caveat that + \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). , .arguments = &.{ "value: anytype", @@ -1594,7 +1816,8 @@ pub const builtins = [_]Builtin{ .documentation = \\Rounds the given floating point number to an integer, towards zero. Uses a dedicated hardware instruction when available. \\ - \\Supports [Floats](https://ziglang.org/documentation/0.9.1/#Floats) and [Vectors](https://ziglang.org/documentation/0.9.1/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). + \\Supports [Floats](https://ziglang.org/documentation/0.9.1/#Floats) and [Vectors](https://ziglang.org/documentation/0.9.1/#Vectors) of floats, with the caveat that + \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). , .arguments = &.{ "value: anytype", @@ -1607,7 +1830,8 @@ pub const builtins = [_]Builtin{ .documentation = \\Rounds the given floating point number to an integer, away from zero. Uses a dedicated hardware instruction when available. \\ - \\Supports [Floats](https://ziglang.org/documentation/0.9.1/#Floats) and [Vectors](https://ziglang.org/documentation/0.9.1/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). + \\Supports [Floats](https://ziglang.org/documentation/0.9.1/#Floats) and [Vectors](https://ziglang.org/documentation/0.9.1/#Vectors) of floats, with the caveat that + \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). , .arguments = &.{ "value: anytype", @@ -1645,8 +1869,26 @@ pub const builtins = [_]Builtin{ .signature = "@This() type", .snippet = "@This()", .documentation = - \\Returns the innermost struct, enum, or union that this function call is inside. This can be useful for an anonymous struct that needs to refer to itself:

{#code_begin|test|this_innermost#} const std = @import("std"); const expect = std.testing.expect; test "@This()" { var items = [_]i32{ 1, 2, 3, 4 }; const list = List(i32){ .items = items[0..] }; try expect(list.length() == 4); } fn List(comptime T: type) type { return struct { const Self = @This(); items: []T, fn length(self: Self) usize { return self.items.len; } }; }` + \\Returns the innermost struct, enum, or union that this function call is inside. This can be useful for an anonymous struct that needs to refer to itself: \\ + \\```zig + \\const std = @import("std"); + \\const expect = std.testing.expect; + \\test "@This()" { + \\ var items = [_]i32{ 1, 2, 3, 4 }; + \\ const list = List(i32){ .items = items[0..] }; + \\ try expect(list.length() == 4); + \\} + \\fn List(comptime T: type) type { + \\ return struct { + \\ const Self = @This(); + \\ items: []T, + \\ fn length(self: Self) usize { + \\ return self.items.len; + \\ } + \\ }; + \\} + \\``` \\When `@This()` is used at file scope, it returns a reference to the struct that corresponds to the current file. , .arguments = &.{}, @@ -1665,14 +1907,12 @@ pub const builtins = [_]Builtin{ \\```zig \\const std = @import("std"); \\const expect = std.testing.expect; - \\ \\test "integer truncation" { \\ var a: u16 = 0xabcd; \\ var b: u8 = @truncate(u8, a); \\ try expect(b == 0xcd); \\} \\``` - \\ \\Use [@intCast](https://ziglang.org/documentation/0.9.1/#intCast) to convert numbers guaranteed to fit the destination type. , .arguments = &.{ @@ -1688,33 +1928,34 @@ pub const builtins = [_]Builtin{ \\This function is the inverse of [@typeInfo](https://ziglang.org/documentation/0.9.1/#typeInfo). It reifies type information into a `type`. \\ \\It is available for the following types: - \\ - `type` - \\ - `noreturn` - \\ - `void` - \\ - `bool` - \\ - [Integers](https://ziglang.org/documentation/0.9.1/#Integers) - The maximum bit count for an integer type is `65535`. - \\ - [Floats](https://ziglang.org/documentation/0.9.1/#Floats) - \\ - [Pointers](https://ziglang.org/documentation/0.9.1/#Pointers) - \\ - `comptime_int` - \\ - `comptime_float` - \\ - `@TypeOf(undefined)` - \\ - `@TypeOf(null)` - \\ - [Arrays](https://ziglang.org/documentation/0.9.1/#Arrays) - \\ - [Optionals](https://ziglang.org/documentation/0.9.1/#Optionals) - \\ - [Error Set Type](https://ziglang.org/documentation/0.9.1/#Error-Set-Type) - \\ - [Error Union Type](https://ziglang.org/documentation/0.9.1/#Error-Union-Type) - \\ - [Vectors](https://ziglang.org/documentation/0.9.1/#Vectors) - \\ - [opaque](https://ziglang.org/documentation/0.9.1/#opaque) - \\ - [@Frame](https://ziglang.org/documentation/0.9.1/#Frame) - \\ - `anyframe` - \\ - [struct](https://ziglang.org/documentation/0.9.1/#struct) - \\ - [enum](https://ziglang.org/documentation/0.9.1/#enum) - \\ - [Enum Literals](https://ziglang.org/documentation/0.9.1/#Enum-Literals) - \\ - [union](https://ziglang.org/documentation/0.9.1/#union) \\ + \\ - `type` + \\ - `noreturn` + \\ - `void` + \\ - `bool` + \\ - [Integers](https://ziglang.org/documentation/0.9.1/#Integers) - The maximum bit count for an integer type is `65535`. + \\ - [Floats](https://ziglang.org/documentation/0.9.1/#Floats) + \\ - [Pointers](https://ziglang.org/documentation/0.9.1/#Pointers) + \\ - `comptime_int` + \\ - `comptime_float` + \\ - `@TypeOf(undefined)` + \\ - `@TypeOf(null)` + \\ - [Arrays](https://ziglang.org/documentation/0.9.1/#Arrays) + \\ - [Optionals](https://ziglang.org/documentation/0.9.1/#Optionals) + \\ - [Error Set Type](https://ziglang.org/documentation/0.9.1/#Error-Set-Type) + \\ - [Error Union Type](https://ziglang.org/documentation/0.9.1/#Error-Union-Type) + \\ - [Vectors](https://ziglang.org/documentation/0.9.1/#Vectors) + \\ - [opaque](https://ziglang.org/documentation/0.9.1/#opaque) + \\ - [@Frame](https://ziglang.org/documentation/0.9.1/#Frame) + \\ - `anyframe` + \\ - [struct](https://ziglang.org/documentation/0.9.1/#struct) + \\ - [enum](https://ziglang.org/documentation/0.9.1/#enum) + \\ - [Enum Literals](https://ziglang.org/documentation/0.9.1/#Enum-Literals) + \\ - [union](https://ziglang.org/documentation/0.9.1/#union) \\For these types, `@Type` is not available: - \\ - [Functions](https://ziglang.org/documentation/0.9.1/#Functions) - \\ - BoundFn + \\ + \\ - [Functions](https://ziglang.org/documentation/0.9.1/#Functions) + \\ - BoundFn , .arguments = &.{ "comptime info: std.builtin.TypeInfo", @@ -1753,7 +1994,23 @@ pub const builtins = [_]Builtin{ .documentation = \\`@TypeOf` is a special builtin function that takes any (nonzero) number of expressions as parameters and returns the type of the result, using [Peer Type Resolution](https://ziglang.org/documentation/0.9.1/#Peer-Type-Resolution). \\ - \\The expressions are evaluated, however they are guaranteed to have no *runtime* side-effects:

{#code_begin|test|no_runtime_side_effects#} const std = @import("std"); const expect = std.testing.expect; test "no runtime side effects" { var data: i32 = 0; const T = @TypeOf(foo(i32, &data)); comptime try expect(T == i32); try expect(data == 0); } fn foo(comptime T: type, ptr: *T) T { ptr.* += 1; return ptr.*; }` + \\The expressions are evaluated, however they are guaranteed to have no + \\**runtime** side-effects: + \\ + \\```zig + \\const std = @import("std"); + \\const expect = std.testing.expect; + \\test "no runtime side effects" { + \\ var data: i32 = 0; + \\ const T = @TypeOf(foo(i32, &data)); + \\ comptime try expect(T == i32); + \\ try expect(data == 0); + \\} + \\fn foo(comptime T: type, ptr: *T) T { + \\ ptr.* += 1; + \\ return ptr.*; + \\} + \\``` , .arguments = &.{ "...", @@ -1775,3 +2032,5 @@ pub const builtins = [_]Builtin{ }, }, }; + +// DO NOT EDIT diff --git a/src/data/generate-data.js b/src/data/generate-data.js deleted file mode 100644 index 9a8c82f..0000000 --- a/src/data/generate-data.js +++ /dev/null @@ -1,107 +0,0 @@ -// Run this in a Chrome developer console. -const builtins = $$("a#toc-Builtin-Functions+ul > li").map(element => { - const anchor = element.querySelector("a").getAttribute("href"); - const code = $(`${anchor}+pre > code`).textContent.replace(/(\r\n|\n|\r)/gm, ""); - - var curr_paragraph = $(`${anchor}+pre+p`); - var doc = ""; - var first = true; - - while (curr_paragraph.nodeName == "P" || curr_paragraph.nodeName == "PRE") { - if (curr_paragraph.innerHTML == "See also:") - break; - - if (!first) { - doc += "\n"; - } else { - first = false; - } - - if (curr_paragraph.nodeName == "PRE") { - doc += "```zig\n"; - curr_paragraph.childNodes[0].childNodes.forEach(elem => { - doc += elem.textContent; - }); - doc += "\n```"; - } else { - curr_paragraph.childNodes.forEach(elem => { - if (elem.nodeName == "CODE") { - console.log(elem.innerHTML); - doc += "`" + elem.innerHTML.replaceAll(/(.+?)<\/span>/gm, "$1") + "`"; - } else - doc += elem.textContent.replace(/(\s\s+)/gm, " "); - }); - } - - curr_paragraph = curr_paragraph.nextElementSibling; - } - return { "name": anchor.substring(1), "code": code, "documentation": doc }; -}); - -// Take output and paste into a .zig file -console.log( - `const Builtin = struct { - name: []const u8, - signature: []const u8, - snippet: []const u8, - documentation: []const u8, - arguments: []const []const u8, -}; - -pub const builtins = [_]Builtin{` + - '\n' + builtins.map(builtin => { - // Make a snippet - const first_paren_idx = builtin.code.indexOf('('); - var snippet = builtin.code.substr(0, first_paren_idx + 1); - var rest = builtin.code.substr(first_paren_idx + 1); - var args = []; - - if (rest[0] == ')') { - snippet += ')'; - } else { - snippet += "${1:" - args.push(""); - - var arg_idx = 2; - var paren_depth = 1; - var skip_space = false; - for (const char of rest) { - if (char == '(') { - paren_depth += 1; - } else if (char == ')') { - paren_depth -= 1; - if (paren_depth == 0) { - snippet += "})"; - break; - } - } else if (char == '"') { - snippet += "\\\""; - args[args.length - 1] += "\\\""; - continue; - } else if (char == ',' && paren_depth == 1) { - snippet += "}, ${" + arg_idx + ':'; - arg_idx += 1; - args.push(""); - skip_space = true; - continue; - } else if (char == ' ' && skip_space) { - continue; - } - - snippet += char; - args[args.length - 1] += char; - skip_space = false; - } - } - - return ` .{ - .name = "@${builtin.name}", - .signature = "${builtin.code.replaceAll('"', "\\\"")}", - .snippet = "${snippet}", - .documentation = - \\\\${builtin.documentation.split('\n').join("\n \\\\")} - , - .arguments = &.{${args.map(x => "\n \"" + x + "\"").join(",") + ((args.length > 0) ? ",\n " : "")}}, - },`; - }).join('\n') + "\n};\n" -); diff --git a/src/data/generate-data.py b/src/data/generate-data.py deleted file mode 100755 index c8f12c4..0000000 --- a/src/data/generate-data.py +++ /dev/null @@ -1,105 +0,0 @@ -#!/usr/bin/env python3 -import urllib.request -import re -import minify_html - -zig_version = 'master' - - -def fix_ul(s): - l = s.split('
  • ') - l.insert(0, '') - return '\n - '.join(l) - - -url = f'https://raw.githubusercontent.com/ziglang/zig/{zig_version}/doc/langref.html.in' -res = urllib.request.urlopen(url) -page = res.read().decode('utf-8') -print('''const Builtin = struct { - name: []const u8, - signature: []const u8, - snippet: []const u8, - documentation: []const u8, - arguments: []const []const u8, -}; - -pub const builtins = [_]Builtin{''') -pattern = r'{#header_open\|(@\S+?)#}(.+?){#header_close#}' -for match in re.finditer(pattern, page, re.M | re.S): - blk = match[2].strip(' \n') - name = match[1] - signature = re.search(r'
    {#syntax#}(.+?){#endsyntax#}
    ', blk, - re.M | re.S)[1].replace('\n ', '').replace('"', '\\"') - snippet = name - if f'{name}()' in signature: - params = None - snippet += '()' - else: - params = [] - i = signature.index('(') + 1 - level = 1 - j = i - while i < len(signature): - if signature[i] == '(': - level += 1 - elif signature[i] == ')': - level -= 1 - if signature[i] == ',' and level == 1: - params.append(signature[j:i]) - j = i + 2 - if level == 0: - break - i += 1 - params.append(signature[j:i]) - snippet += '(${' - i = 1 - for param in params: - snippet += f'{i}:{param}}}, ${{' - i += 1 - snippet = snippet[:-4] + ')' - docs = re.sub(r'{#see_also\|[^#]+#}', '', blk) - docs = re.sub( - r' {#code_begin\|(obj|syntax|(test(\|(call|truncate))?))#}\n', '
    {#syntax#}', docs)
    -    docs = re.sub(
    -        r'      {#code_begin\|test_(err|safety)\|[^#]+#}\n', '      
    {#syntax#}', docs)
    -    docs = docs.replace('      {#code_release_fast#}\n', '')
    -    docs = docs.replace('      {#code_end#}', '{#endsyntax#}
    ') - docs = docs.replace('\n{#endsyntax#}
    ', '{#endsyntax#}
  • ') - docs = minify_html.minify(docs) - prefix = '

    ' - docs = docs[docs.index(prefix)+len(prefix):] - docs = docs.replace('

    ', '\n\n') - docs = re.sub(r'{#(end)?syntax#}', '`', docs) - # @cDefine - docs = re.sub(r'

    ]+>([^<]+)
    ', '`\\1`', docs) - docs = re.sub(r'', '`', docs) - docs = docs.replace('
    `', '\n\n```zig\n')
    -    docs = docs.replace('`
    ', '\n```') - # @setFloatMode - docs = docs.replace('```<', '```\n<') - # @TypeOf - docs = re.sub(r'', '*', docs) - docs = re.sub(r']+)>([^<]+)', '[\\2](\\1)', docs) - docs = re.sub(r'{#link\|([^|#]+)\|([^|#]+)#}', - lambda m: f'[{m[1]}](https://ziglang.org/documentation/{zig_version}/#{m[2].replace(" ","-")})', docs) - docs = re.sub( - r'{#link\|([^|#]+)#}', lambda m: f'[{m[1]}](https://ziglang.org/documentation/{zig_version}/#{m[1].replace(" ","-").replace("@","")})', docs) - docs = re.sub(r'
    • (.+?)
    ', lambda m: fix_ul(m[1]), docs) - - print(' .{') - print(f' .name = "{name}",') - print(f' .signature = "{signature}",') - print(f' .snippet = "{snippet}",') - print(' .documentation =') - for line in docs.splitlines(): - print(r' \\' + line) - print(' ,') - if params is None: - print(' .arguments = &.{},') - else: - print(' .arguments = &.{') - for param in params: - print(f' "{param}",') - print(' },') - print(' },') -print('};') diff --git a/src/data/master.zig b/src/data/master.zig index 8896e78..cc7d3e8 100644 --- a/src/data/master.zig +++ b/src/data/master.zig @@ -1,3 +1,8 @@ +//! DO NOT EDIT +//! If you want to update this file run: +//! `zig build gen -- --generate-version-data master` (requires an internet connection) +//! GENERATED BY src/config_gen/config_gen.zig + const Builtin = struct { name: []const u8, signature: []const u8, @@ -58,8 +63,7 @@ pub const builtins = [_]Builtin{ \\ assert(*u32 == *align(@alignOf(u32)) u32); \\} \\``` - \\ - \\The result is a target-specific compile time constant. It is guaranteed to be less than or equal to [@sizeOf(T)](https://ziglang.org/documentation/master/#@sizeOf). + \\The result is a target-specific compile time constant. It is guaranteed to be less than or equal to [@sizeOf(T)](https://ziglang.org/documentation/master/#sizeOf). , .arguments = &.{ "comptime T: type", @@ -102,15 +106,16 @@ pub const builtins = [_]Builtin{ \\`T` must be a pointer, a `bool`, a float, an integer or an enum. \\ \\Supported operations: - \\ - `.Xchg` - stores the operand unmodified. Supports enums, integers and floats. - \\ - `.Add` - for integers, twos complement wraparound addition. Also supports [Floats](https://ziglang.org/documentation/master/#Floats). - \\ - `.Sub` - for integers, twos complement wraparound subtraction. Also supports [Floats](https://ziglang.org/documentation/master/#Floats). - \\ - `.And` - bitwise and - \\ - `.Nand` - bitwise nand - \\ - `.Or` - bitwise or - \\ - `.Xor` - bitwise xor - \\ - `.Max` - stores the operand if it is larger. Supports integers and floats. - \\ - `.Min` - stores the operand if it is smaller. Supports integers and floats. + \\ + \\ - `.Xchg` - stores the operand unmodified. Supports enums, integers and floats. + \\ - `.Add` - for integers, twos complement wraparound addition. Also supports [Floats](https://ziglang.org/documentation/master/#Floats). + \\ - `.Sub` - for integers, twos complement wraparound subtraction. Also supports [Floats](https://ziglang.org/documentation/master/#Floats). + \\ - `.And` - bitwise and + \\ - `.Nand` - bitwise nand + \\ - `.Or` - bitwise or + \\ - `.Xor` - bitwise xor + \\ - `.Max` - stores the operand if it is larger. Supports integers and floats. + \\ - `.Min` - stores the operand if it is smaller. Supports integers and floats. , .arguments = &.{ "comptime T: type", @@ -148,9 +153,9 @@ pub const builtins = [_]Builtin{ \\Asserts that `@typeInfo(DestType) != .Pointer`. Use `@ptrCast` or `@intToPtr` if you need this. \\ \\Can be used for these things for example: - \\ - Convert `f32` to `u32` bits - \\ - Convert `i32` to `u32` preserving twos complement \\ + \\ - Convert `f32` to `u32` bits + \\ - Convert `i32` to `u32` preserving twos complement \\Works at compile-time if `value` is known at compile time. It's a compile error to bitcast a value of undefined layout; this means that, besides the restriction from types which possess dedicated casting builtins (enums, pointers, error sets), bare structs, error unions, slices, optionals, and any other type without a well-defined memory layout, also cannot be used in this operation. , .arguments = &.{ @@ -278,17 +283,43 @@ pub const builtins = [_]Builtin{ \\ \\```zig \\const expect = @import("std").testing.expect; - \\ \\test "noinline function call" { \\ try expect(@call(.auto, add, .{3, 9}) == 12); \\} - \\ \\fn add(a: i32, b: i32) i32 { \\ return a + b; \\} \\``` + \\`@call` allows more flexibility than normal function call syntax does. The `CallModifier` enum is reproduced here: \\ - \\`@call` allows more flexibility than normal function call syntax does. The `CallModifier` enum is reproduced here:

    {#syntax_block|zig|builtin.CallModifier struct#} pub const CallModifier = enum { /// Equivalent to function call syntax. auto, /// Equivalent to async keyword used with function call syntax. async_kw, /// Prevents tail call optimization. This guarantees that the return /// address will point to the callsite, as opposed to the callsite's /// callsite. If the call is otherwise required to be tail-called /// or inlined, a compile error is emitted instead. never_tail, /// Guarantees that the call will not be inlined. If the call is /// otherwise required to be inlined, a compile error is emitted instead. never_inline, /// Asserts that the function call will not suspend. This allows a /// non-async function to call an async function. no_async, /// Guarantees that the call will be generated with tail call optimization. /// If this is not possible, a compile error is emitted instead. always_tail, /// Guarantees that the call will inlined at the callsite. /// If this is not possible, a compile error is emitted instead. always_inline, /// Evaluates the call at compile-time. If the call cannot be completed at /// compile-time, a compile error is emitted instead. compile_time, }; {#end_syntax_block#} + \\```zig + \\pub const CallModifier = enum { + \\ /// Equivalent to function call syntax. + \\ auto, + \\ /// Equivalent to async keyword used with function call syntax. + \\ async_kw, + \\ /// Prevents tail call optimization. This guarantees that the return + \\ /// address will point to the callsite, as opposed to the callsite's + \\ /// callsite. If the call is otherwise required to be tail-called + \\ /// or inlined, a compile error is emitted instead. + \\ never_tail, + \\ /// Guarantees that the call will not be inlined. If the call is + \\ /// otherwise required to be inlined, a compile error is emitted instead. + \\ never_inline, + \\ /// Asserts that the function call will not suspend. This allows a + \\ /// non-async function to call an async function. + \\ no_async, + \\ /// Guarantees that the call will be generated with tail call optimization. + \\ /// If this is not possible, a compile error is emitted instead. + \\ always_tail, + \\ /// Guarantees that the call will inlined at the callsite. + \\ /// If this is not possible, a compile error is emitted instead. + \\ always_inline, + \\ /// Evaluates the call at compile-time. If the call cannot be completed at + \\ /// compile-time, a compile error is emitted instead. + \\ compile_time, + \\}; + \\``` , .arguments = &.{ "modifier: std.builtin.CallModifier", @@ -303,15 +334,14 @@ pub const builtins = [_]Builtin{ .documentation = \\This function can only occur inside `@cImport`. \\ - \\This appends `#define $name $value` to the `@cImport` temporary buffer. + \\This appends + \\`#define $name $value`to the `@cImport` temporary buffer. \\ - \\To define without a value, like this:`#define _GNU_SOURCE` + \\To define without a value, like this: \\ - \\Use the void value, like this: + \\`#define _GNU_SOURCE`Use the void value, like this: \\ - \\```zig - \\@cDefine("_GNU_SOURCE", {}) - \\``` + \\`@cDefine("_GNU_SOURCE", {})` , .arguments = &.{ "comptime name: []u8", @@ -330,8 +360,9 @@ pub const builtins = [_]Builtin{ \\Usually you should only have one `@cImport` in your entire application, because it saves the compiler from invoking clang multiple times, and prevents inline functions from being duplicated. \\ \\Reasons for having multiple `@cImport` expressions would be: - \\ - To avoid a symbol collision, for example if foo.h and bar.h both `#define CONNECTION_COUNT` - \\ - To analyze the C code with different preprocessor defines + \\ + \\ - To avoid a symbol collision, for example if foo.h and bar.h both + \\`#define CONNECTION_COUNT` - To analyze the C code with different preprocessor defines , .arguments = &.{ "expression", @@ -344,7 +375,8 @@ pub const builtins = [_]Builtin{ .documentation = \\This function can only occur inside `@cImport`. \\ - \\This appends `#include <$path>\n` to the `c_import` temporary buffer. + \\This appends + \\`#include <$path>\n`to the `c_import` temporary buffer. , .arguments = &.{ "comptime path: []u8", @@ -387,7 +419,6 @@ pub const builtins = [_]Builtin{ \\ } \\} \\``` - \\ \\If you are using cmpxchg in a loop, [@cmpxchgWeak](https://ziglang.org/documentation/master/#cmpxchgWeak) is the better choice, because it can be implemented more efficiently in machine instructions. \\ \\`T` must be a pointer, a `bool`, a float, an integer or an enum. @@ -408,8 +439,19 @@ pub const builtins = [_]Builtin{ .signature = "@cmpxchgWeak(comptime T: type, ptr: *T, expected_value: T, new_value: T, success_order: AtomicOrder, fail_order: AtomicOrder) ?T", .snippet = "@cmpxchgWeak(${1:comptime T: type}, ${2:ptr: *T}, ${3:expected_value: T}, ${4:new_value: T}, ${5:success_order: AtomicOrder}, ${6:fail_order: AtomicOrder})", .documentation = - \\This function performs a weak atomic compare exchange operation. It's the equivalent of this code, except atomic:

    {#syntax_block|zig|cmpxchgWeakButNotAtomic#} fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_value: T) ?T { const old_value = ptr.*; if (old_value == expected_value and usuallyTrueButSometimesFalse()) { ptr.* = new_value; return null; } else { return old_value; } } {#end_syntax_block#} + \\This function performs a weak atomic compare exchange operation. It's the equivalent of this code, except atomic: \\ + \\```zig + \\fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_value: T) ?T { + \\ const old_value = ptr.*; + \\ if (old_value == expected_value and usuallyTrueButSometimesFalse()) { + \\ ptr.* = new_value; + \\ return null; + \\ } else { + \\ return old_value; + \\ } + \\} + \\``` \\If you are using cmpxchg in a loop, the sporadic failure will be no problem, and `cmpxchgWeak` is the better choice, because it can be implemented more efficiently in machine instructions. However if you need a stronger guarantee, use [@cmpxchgStrong](https://ziglang.org/documentation/master/#cmpxchgStrong). \\ \\`T` must be a pointer, a `bool`, a float, an integer or an enum. @@ -451,22 +493,30 @@ pub const builtins = [_]Builtin{ \\ \\```zig \\const print = @import("std").debug.print; - \\ \\const num1 = blk: { \\ var val1: i32 = 99; \\ @compileLog("comptime val1 = ", val1); \\ val1 = val1 + 1; \\ break :blk val1; \\}; - \\ \\test "main" { \\ @compileLog("comptime in main"); - \\ \\ print("Runtime in main, num1 = {}.\n", .{num1}); \\} \\``` + \\If all `@compileLog` calls are removed or not encountered by analysis, the program compiles successfully and the generated executable prints: \\ - \\If all `@compileLog` calls are removed or not encountered by analysis, the program compiles successfully and the generated executable prints:

    {#code_begin|test|without_compileLog#} const print = @import("std").debug.print; const num1 = blk: { var val1: i32 = 99; val1 = val1 + 1; break :blk val1; }; test "main" { print("Runtime in main, num1 = {}.\n", .{num1}); }` + \\```zig + \\const print = @import("std").debug.print; + \\const num1 = blk: { + \\ var val1: i32 = 99; + \\ val1 = val1 + 1; + \\ break :blk val1; + \\}; + \\test "main" { + \\ print("Runtime in main, num1 = {}.\n", .{num1}); + \\} + \\``` , .arguments = &.{ "args: ...", @@ -498,7 +548,8 @@ pub const builtins = [_]Builtin{ .documentation = \\This function can only occur inside `@cImport`. \\ - \\This appends `#undef $name` to the `@cImport` temporary buffer. + \\This appends + \\`#undef $name`to the `@cImport` temporary buffer. , .arguments = &.{ "comptime name: []u8", @@ -553,9 +604,9 @@ pub const builtins = [_]Builtin{ .snippet = "@divExact(${1:numerator: T}, ${2:denominator: T})", .documentation = \\Exact division. Caller guarantees `denominator != 0` and `@divTrunc(numerator, denominator) * denominator == numerator`. - \\ - `@divExact(6, 3) == 2` - \\ - `@divExact(a, b) * b == a` \\ + \\ - `@divExact(6, 3) == 2` + \\ - `@divExact(a, b) * b == a` \\For a function that returns a possible error code, use `@import("std").math.divExact`. , .arguments = &.{ @@ -569,9 +620,9 @@ pub const builtins = [_]Builtin{ .snippet = "@divFloor(${1:numerator: T}, ${2:denominator: T})", .documentation = \\Floored division. Rounds toward negative infinity. For unsigned integers it is the same as `numerator / denominator`. Caller guarantees `denominator != 0` and `!(@typeInfo(T) == .Int and T.is_signed and numerator == std.math.minInt(T) and denominator == -1)`. - \\ - `@divFloor(-5, 3) == -2` - \\ - `(@divFloor(a, b) * b) + @mod(a, b) == a` \\ + \\ - `@divFloor(-5, 3) == -2` + \\ - `(@divFloor(a, b) * b) + @mod(a, b) == a` \\For a function that returns a possible error code, use `@import("std").math.divFloor`. , .arguments = &.{ @@ -585,9 +636,9 @@ pub const builtins = [_]Builtin{ .snippet = "@divTrunc(${1:numerator: T}, ${2:denominator: T})", .documentation = \\Truncated division. Rounds toward zero. For unsigned integers it is the same as `numerator / denominator`. Caller guarantees `denominator != 0` and `!(@typeInfo(T) == .Int and T.is_signed and numerator == std.math.minInt(T) and denominator == -1)`. - \\ - `@divTrunc(-5, 3) == -1` - \\ - `(@divTrunc(a, b) * b) + @rem(a, b) == a` \\ + \\ - `@divTrunc(-5, 3) == -1` + \\ - `(@divTrunc(a, b) * b) + @rem(a, b) == a` \\For a function that returns a possible error code, use `@import("std").math.divTrunc`. , .arguments = &.{ @@ -649,10 +700,10 @@ pub const builtins = [_]Builtin{ .snippet = "@errorToInt(${1:err: anytype})", .documentation = \\Supports the following types: - \\ - [The Global Error Set](https://ziglang.org/documentation/master/#The-Global-Error-Set) - \\ - [Error Set Type](https://ziglang.org/documentation/master/#Error-Set-Type) - \\ - [Error Union Type](https://ziglang.org/documentation/master/#Error-Union-Type) \\ + \\ - [The Global Error Set](https://ziglang.org/documentation/master/#The-Global-Error-Set) + \\ - [Error Set Type](https://ziglang.org/documentation/master/#Error-Set-Type) + \\ - [Error Union Type](https://ziglang.org/documentation/master/#Error-Union-Type) \\Converts an error to the integer representation of an error. \\ \\It is generally recommended to avoid this cast, as the integer representation of an error is not stable across source code changes. @@ -680,37 +731,28 @@ pub const builtins = [_]Builtin{ .documentation = \\Creates a symbol in the output object file. \\ - \\`declaration` must be one of two things: - \\ - An identifier (`x`) identifying a [function](https://ziglang.org/documentation/master/#Functions) or a [variable](https://ziglang.org/documentation/master/#Container-Level-Variables). - \\ - Field access (`x.y`) looking up a [function](https://ziglang.org/documentation/master/#Functions) or a [variable](https://ziglang.org/documentation/master/#Container-Level-Variables). + \\`declaration`must be one of two things: \\ - \\This builtin can be called from a [comptime](https://ziglang.org/documentation/master/#comptime) block to conditionally export symbols. When `declaration` is a function with the C calling convention and `options.linkage` is `Strong`, this is equivalent to the `export` keyword used on a function: + \\ - An identifier (`x`) identifying a [function](https://ziglang.org/documentation/master/#Functions) or a [variable](https://ziglang.org/documentation/master/#Container-Level-Variables). + \\ - Field access (`x.y`) looking up a [function](https://ziglang.org/documentation/master/#Functions) or a [variable](https://ziglang.org/documentation/master/#Container-Level-Variables). + \\This builtin can be called from a [comptime](https://ziglang.org/documentation/master/#comptime) block to conditionally export symbols. When + \\`declaration`is a function with the C calling convention and `options.linkage` is `Strong`, this is equivalent to the `export` keyword used on a function: \\ \\```zig \\comptime { \\ @export(internalName, .{ .name = "foo", .linkage = .Strong }); \\} - \\ \\fn internalName() callconv(.C) void {} \\``` - \\ \\This is equivalent to: \\ - \\```zig - \\export fn foo() void {} - \\``` - \\ + \\`export fn foo() void {}` \\Note that even when using `export`, the `@"foo"` syntax for [identifiers](https://ziglang.org/documentation/master/#Identifiers) can be used to choose any string for the symbol name: \\ - \\```zig - \\export fn @"A function name that is a complete sentence."() void {} - \\``` - \\ + \\`export fn @"A function name that is a complete sentence."() void {}` \\When looking at the resulting object, you can see the symbol is used verbatim: \\ - \\```zig - \\00000000000001f0 T A function name that is a complete sentence. - \\``` + \\`00000000000001f0 T A function name that is a complete sentence.` , .arguments = &.{ "declaration", @@ -747,7 +789,30 @@ pub const builtins = [_]Builtin{ .signature = "@field(lhs: anytype, comptime field_name: []const u8) (field)", .snippet = "@field(${1:lhs: anytype}, ${2:comptime field_name: []const u8})", .documentation = - \\Performs field access by a compile-time string. Works on both fields and declarations.

    {#code_begin|test|field_decl_access_by_string#} const std = @import("std"); const Point = struct { x: u32, y: u32, pub var z: u32 = 1; }; test "field access by string" { const expect = std.testing.expect; var p = Point{ .x = 0, .y = 0 }; @field(p, "x") = 4; @field(p, "y") = @field(p, "x") + 1; try expect(@field(p, "x") == 4); try expect(@field(p, "y") == 5); } test "decl access by string" { const expect = std.testing.expect; try expect(@field(Point, "z") == 1); @field(Point, "z") = 2; try expect(@field(Point, "z") == 2); }` + \\Performs field access by a compile-time string. Works on both fields and declarations. + \\ + \\```zig + \\const std = @import("std"); + \\const Point = struct { + \\ x: u32, + \\ y: u32, + \\ pub var z: u32 = 1; + \\}; + \\test "field access by string" { + \\ const expect = std.testing.expect; + \\ var p = Point{ .x = 0, .y = 0 }; + \\ @field(p, "x") = 4; + \\ @field(p, "y") = @field(p, "x") + 1; + \\ try expect(@field(p, "x") == 4); + \\ try expect(@field(p, "y") == 5); + \\} + \\test "decl access by string" { + \\ const expect = std.testing.expect; + \\ try expect(@field(Point, "z") == 1); + \\ @field(Point, "z") = 2; + \\ try expect(@field(Point, "z") == 2); + \\} + \\``` , .arguments = &.{ "lhs: anytype", @@ -756,7 +821,7 @@ pub const builtins = [_]Builtin{ }, .{ .name = "@fieldParentPtr", - .signature = "@fieldParentPtr(comptime ParentType: type, comptime field_name: []const u8, field_ptr: *T) *ParentType", + .signature = "@fieldParentPtr(comptime ParentType: type, comptime field_name: []const u8, field_ptr: *T) *ParentType", .snippet = "@fieldParentPtr(${1:comptime ParentType: type}, ${2:comptime field_name: []const u8}, ${3:field_ptr: *T})", .documentation = \\Given a pointer to a field, returns the base pointer of a struct. @@ -811,7 +876,27 @@ pub const builtins = [_]Builtin{ .signature = "@hasDecl(comptime Container: type, comptime name: []const u8) bool", .snippet = "@hasDecl(${1:comptime Container: type}, ${2:comptime name: []const u8})", .documentation = - \\Returns whether or not a [container](https://ziglang.org/documentation/master/#Containers) has a declaration matching `name`.

    {#code_begin|test|hasDecl#} const std = @import("std"); const expect = std.testing.expect; const Foo = struct { nope: i32, pub var blah = "xxx"; const hi = 1; }; test "@hasDecl" { try expect(@hasDecl(Foo, "blah")); // Even though `hi` is private, @hasDecl returns true because this test is // in the same file scope as Foo. It would return false if Foo was declared // in a different file. try expect(@hasDecl(Foo, "hi")); // @hasDecl is for declarations; not fields. try expect(!@hasDecl(Foo, "nope")); try expect(!@hasDecl(Foo, "nope1234")); }` + \\Returns whether or not a [container](https://ziglang.org/documentation/master/#Containers) has a declaration matching `name`. + \\ + \\```zig + \\const std = @import("std"); + \\const expect = std.testing.expect; + \\const Foo = struct { + \\ nope: i32, + \\ pub var blah = "xxx"; + \\ const hi = 1; + \\}; + \\test "@hasDecl" { + \\ try expect(@hasDecl(Foo, "blah")); + \\ // Even though `hi` is private, @hasDecl returns true because this test is + \\ // in the same file scope as Foo. It would return false if Foo was declared + \\ // in a different file. + \\ try expect(@hasDecl(Foo, "hi")); + \\ // @hasDecl is for declarations; not fields. + \\ try expect(!@hasDecl(Foo, "nope")); + \\ try expect(!@hasDecl(Foo, "nope1234")); + \\} + \\``` , .arguments = &.{ "comptime Container: type", @@ -848,9 +933,12 @@ pub const builtins = [_]Builtin{ \\`path` can be a relative path or it can be the name of a package. If it is a relative path, it is relative to the file that contains the `@import` function call. \\ \\The following packages are always available: - \\ - `@import("std")` - Zig Standard Library - \\ - `@import("builtin")` - Target-specific information. The command `zig build-exe --show-builtin` outputs the source to stdout for reference. - \\ - `@import("root")` - Points to the root source file. This is usually `src/main.zig` but it depends on what file is chosen to be built. + \\ + \\ - `@import("std")` - Zig Standard Library + \\ - `@import("builtin")` - Target-specific information. The command + \\`zig build-exe --show-builtin`outputs the source to stdout for reference. + \\ - `@import("root")` - Points to the root source file. This is usually + \\`src/main.zig`but it depends on what file is chosen to be built. , .arguments = &.{ "comptime path: []u8", @@ -870,7 +958,6 @@ pub const builtins = [_]Builtin{ \\ _ = b; \\} \\``` - \\ \\To truncate the significant bits of a number out of range of the destination type, use [@truncate](https://ziglang.org/documentation/master/#truncate). \\ \\If `T` is `comptime_int`, then this is semantically equivalent to [Type Coercion](https://ziglang.org/documentation/master/#Type-Coercion). @@ -897,7 +984,7 @@ pub const builtins = [_]Builtin{ .{ .name = "@intToError", .signature = "@intToError(value: std.meta.Int(.unsigned, @sizeOf(anyerror) * 8)) anyerror", - .snippet = "@intToError(${1:value: std.meta.Int(.unsigned, @sizeOf(anyerror) * 8)})", + .snippet = "@intToError(${1:value: std.meta.Int(.unsigned, @sizeOf(anyerror) * 8})", .documentation = \\Converts from the integer representation of an error into [The Global Error Set](https://ziglang.org/documentation/master/#The-Global-Error-Set) type. \\ @@ -906,7 +993,7 @@ pub const builtins = [_]Builtin{ \\Attempting to convert an integer that does not correspond to any error results in safety-protected [Undefined Behavior](https://ziglang.org/documentation/master/#Undefined-Behavior). , .arguments = &.{ - "value: std.meta.Int(.unsigned, @sizeOf(anyerror) * 8)", + "value: std.meta.Int(.unsigned, @sizeOf(anyerror) * 8", }, }, .{ @@ -958,10 +1045,7 @@ pub const builtins = [_]Builtin{ \\ \\This function is a low level intrinsic with no safety mechanisms. Most code should not use this function, instead using something like this: \\ - \\```zig - \\for (source[0..byte_count]) |b, i| dest[i] = b; - \\``` - \\ + \\`for (source[0..byte_count]) |b, i| dest[i] = b;` \\The optimizer is intelligent enough to turn the above snippet into a memcpy. \\ \\There is also a standard library function for this: @@ -986,10 +1070,7 @@ pub const builtins = [_]Builtin{ \\ \\This function is a low level intrinsic with no safety mechanisms. Most code should not use this function, instead using something like this: \\ - \\```zig - \\for (dest[0..byte_count]) |*b| b.* = c; - \\``` - \\ + \\`for (dest[0..byte_count]) |*b| b.* = c;` \\The optimizer is intelligent enough to turn the above snippet into a memset. \\ \\There is also a standard library function for this: @@ -1039,7 +1120,19 @@ pub const builtins = [_]Builtin{ .documentation = \\This function increases the size of the Wasm memory identified by `index` by `delta` in units of unsigned number of Wasm pages. Note that each Wasm page is 64KB in size. On success, returns previous memory size; on failure, if the allocation fails, returns -1. \\ - \\This function is a low level intrinsic with no safety mechanisms usually useful for allocator designers targeting Wasm. So unless you are writing a new allocator from scratch, you should use something like `@import("std").heap.WasmPageAllocator`.

    {#code_begin|test|wasmMemoryGrow#} const std = @import("std"); const native_arch = @import("builtin").target.cpu.arch; const expect = std.testing.expect; test "@wasmMemoryGrow" { if (native_arch != .wasm32) return error.SkipZigTest; var prev = @wasmMemorySize(0); try expect(prev == @wasmMemoryGrow(0, 1)); try expect(prev + 1 == @wasmMemorySize(0)); }` + \\This function is a low level intrinsic with no safety mechanisms usually useful for allocator designers targeting Wasm. So unless you are writing a new allocator from scratch, you should use something like `@import("std").heap.WasmPageAllocator`. + \\ + \\```zig + \\const std = @import("std"); + \\const native_arch = @import("builtin").target.cpu.arch; + \\const expect = std.testing.expect; + \\test "@wasmMemoryGrow" { + \\ if (native_arch != .wasm32) return error.SkipZigTest; + \\ var prev = @wasmMemorySize(0); + \\ try expect(prev == @wasmMemoryGrow(0, 1)); + \\ try expect(prev + 1 == @wasmMemorySize(0)); + \\} + \\``` , .arguments = &.{ "index: u32", @@ -1052,9 +1145,9 @@ pub const builtins = [_]Builtin{ .snippet = "@mod(${1:numerator: T}, ${2:denominator: T})", .documentation = \\Modulus division. For unsigned integers this is the same as `numerator % denominator`. Caller guarantees `denominator > 0`, otherwise the operation will result in a [Remainder Division by Zero](https://ziglang.org/documentation/master/#Remainder-Division-by-Zero) when runtime safety checks are enabled. - \\ - `@mod(-5, 3) == 1` - \\ - `(@divFloor(a, b) * b) + @mod(a, b) == a` \\ + \\ - `@mod(-5, 3) == 1` + \\ - `(@divFloor(a, b) * b) + @mod(a, b) == a` \\For a function that returns an error code, see `@import("std").math.mod`. , .arguments = &.{ @@ -1082,8 +1175,9 @@ pub const builtins = [_]Builtin{ \\Invokes the panic handler function. By default the panic handler function calls the public `panic` function exposed in the root source file, or if there is not one specified, the `std.builtin.default_panic` function from `std/builtin.zig`. \\ \\Generally it is better to use `@import("std").debug.panic`. However, `@panic` can be useful for 2 scenarios: - \\ - From library code, calling the programmer's panic function if they exposed one in the root source file. - \\ - When mixing C and Zig code, calling the canonical panic implementation across multiple .o files. + \\ + \\ - From library code, calling the programmer's panic function if they exposed one in the root source file. + \\ - When mixing C and Zig code, calling the canonical panic implementation across multiple .o files. , .arguments = &.{ "message: []const u8", @@ -1115,7 +1209,32 @@ pub const builtins = [_]Builtin{ \\ \\The `ptr` argument may be any pointer type and determines the memory address to prefetch. This function does not dereference the pointer, it is perfectly legal to pass a pointer to invalid memory to this function and no illegal behavior will result. \\ - \\The `options` argument is the following struct:

    {#code_begin|syntax|builtin#} /// This data structure is used by the Zig language code generation and /// therefore must be kept in sync with the compiler implementation. pub const PrefetchOptions = struct { /// Whether the prefetch should prepare for a read or a write. rw: Rw = .read, /// 0 means no temporal locality. That is, the data can be immediately /// dropped from the cache after it is accessed. /// /// 3 means high temporal locality. That is, the data should be kept in /// the cache as it is likely to be accessed again soon. locality: u2 = 3, /// The cache that the prefetch should be preformed on. cache: Cache = .data, pub const Rw = enum { read, write, }; pub const Cache = enum { instruction, data, }; };` + \\The `options` argument is the following struct: + \\ + \\```zig + \\/// This data structure is used by the Zig language code generation and + \\/// therefore must be kept in sync with the compiler implementation. + \\pub const PrefetchOptions = struct { + \\ /// Whether the prefetch should prepare for a read or a write. + \\ rw: Rw = .read, + \\ /// 0 means no temporal locality. That is, the data can be immediately + \\ /// dropped from the cache after it is accessed. + \\ /// + \\ /// 3 means high temporal locality. That is, the data should be kept in + \\ /// the cache as it is likely to be accessed again soon. + \\ locality: u2 = 3, + \\ /// The cache that the prefetch should be preformed on. + \\ cache: Cache = .data, + \\ pub const Rw = enum { + \\ read, + \\ write, + \\ }; + \\ pub const Cache = enum { + \\ instruction, + \\ data, + \\ }; + \\}; + \\``` , .arguments = &.{ "ptr: anytype", @@ -1155,9 +1274,9 @@ pub const builtins = [_]Builtin{ .snippet = "@rem(${1:numerator: T}, ${2:denominator: T})", .documentation = \\Remainder division. For unsigned integers this is the same as `numerator % denominator`. Caller guarantees `denominator > 0`, otherwise the operation will result in a [Remainder Division by Zero](https://ziglang.org/documentation/master/#Remainder-Division-by-Zero) when runtime safety checks are enabled. - \\ - `@rem(-5, 3) == -2` - \\ - `(@divTrunc(a, b) * b) + @rem(a, b) == a` \\ + \\ - `@rem(-5, 3) == -2` + \\ - `(@divTrunc(a, b) * b) + @rem(a, b) == a` \\For a function that returns an error code, see `@import("std").math.rem`. , .arguments = &.{ @@ -1225,16 +1344,16 @@ pub const builtins = [_]Builtin{ \\ \\Example: \\ - \\```zig - \\test "foo" { - \\ comptime { - \\ var i = 0; - \\ while (i < 1001) : (i += 1) {} + \\1001) : (i += 1) {} \\ } \\} \\``` + \\Now we use `@setEvalBranchQuota`: \\ - \\Now we use `@setEvalBranchQuota`:

    {#code_begin|test|setEvalBranchQuota#} test "foo" { comptime { @setEvalBranchQuota(1001); var i = 0; while (i < 1001) : (i += 1) {} } }` + \\1001) : (i += 1) {} + \\ } + \\} + \\``` , .arguments = &.{ "comptime new_quota: u32", @@ -1253,16 +1372,16 @@ pub const builtins = [_]Builtin{ \\ Optimized, \\}; \\``` - \\ - \\ - `Strict` (default) - Floating point operations follow strict IEEE compliance. - \\ - `Optimized` - Floating point operations may do all of the following:
      - \\ - Assume the arguments and result are not NaN. Optimizations are required to retain defined behavior over NaNs, but the value of the result is undefined. - \\ - Assume the arguments and result are not +/-Inf. Optimizations are required to retain defined behavior over +/-Inf, but the value of the result is undefined. - \\ - Treat the sign of a zero argument or result as insignificant. - \\ - Use the reciprocal of an argument rather than perform division. - \\ - Perform floating-point contraction (e.g. fusing a multiply followed by an addition into a fused multiply-add). - \\ - Perform algebraically equivalent transformations that may change results in floating point (e.g. reassociate). This is equivalent to `-ffast-math` in GCC.
    - \\ + \\ - `Strict` (default) - Floating point operations follow strict IEEE compliance. + \\ - `Optimized` - Floating point operations may do all of the following: + \\ - Assume the arguments and result are not NaN. Optimizations are required to retain defined behavior over NaNs, but the value of the result is undefined. + \\ - Assume the arguments and result are not +/-Inf. Optimizations are required to retain defined behavior over +/-Inf, but the value of the result is undefined. + \\ - Treat the sign of a zero argument or result as insignificant. + \\ - Use the reciprocal of an argument rather than perform division. + \\ - Perform floating-point contraction (e.g. fusing a multiply followed by an addition into a fused multiply-add). + \\ - Perform algebraically equivalent transformations that may change results in floating point (e.g. reassociate). + \\This is equivalent to + \\`-ffast-math`in GCC. \\The floating point mode is inherited by child scopes, and can be overridden in any scope. You can set the floating point mode in a struct or module scope by using a comptime block. , .arguments = &.{ @@ -1288,7 +1407,6 @@ pub const builtins = [_]Builtin{ \\ @setRuntimeSafety(true); \\ var x: u8 = 255; \\ x += 1; - \\ \\ { \\ // The value can be overridden at any scope. So here integer overflow \\ // would not be caught in any build mode. @@ -1299,8 +1417,9 @@ pub const builtins = [_]Builtin{ \\ } \\} \\``` - \\ - \\Note: it is [planned](https://github.com/ziglang/zig/issues/978) to replace `@setRuntimeSafety` with `@optimizeFor` + \\Note: it is + \\[planned](https://github.com/ziglang/zig/issues/978)to replace `@setRuntimeSafety` with + \\`@optimizeFor` , .arguments = &.{ "comptime safety_on: bool", @@ -1311,7 +1430,7 @@ pub const builtins = [_]Builtin{ .signature = "@shlExact(value: T, shift_amt: Log2T) T", .snippet = "@shlExact(${1:value: T}, ${2:shift_amt: Log2T})", .documentation = - \\Performs the left shift operation (`<<`). For unsigned integers, the result is [undefined](https://ziglang.org/documentation/master/#undefined) if any 1 bits are shifted out. For signed integers, the result is [undefined](https://ziglang.org/documentation/master/#undefined) if any bits that disagree with the resultant sign bit are shifted out. + \\`). For unsigned integers, the result is [undefined](https://ziglang.org/documentation/master/#undefined) if any 1 bits are shifted out. For signed integers, the result is [undefined](https://ziglang.org/documentation/master/#undefined) if any bits that disagree with the resultant sign bit are shifted out. \\ \\The type of `shift_amt` is an unsigned integer with `log2(@typeInfo(T).Int.bits)` bits. This is because `shift_amt >= @typeInfo(T).Int.bits` is undefined behavior. , @@ -1325,7 +1444,7 @@ pub const builtins = [_]Builtin{ .signature = "@shlWithOverflow(a: anytype, shift_amt: Log2T) struct { @TypeOf(a), u1 }", .snippet = "@shlWithOverflow(${1:a: anytype}, ${2:shift_amt: Log2T})", .documentation = - \\Performs `a << b` and returns a tuple with the result and a possible overflow bit. + \\b` and returns a tuple with the result and a possible overflow bit. \\ \\The type of `shift_amt` is an unsigned integer with `log2(@typeInfo(@TypeOf(a)).Int.bits)` bits. This is because `shift_amt >= @typeInfo(@TypeOf(a)).Int.bits` is undefined behavior. , @@ -1363,7 +1482,25 @@ pub const builtins = [_]Builtin{ \\ \\If `a` or `b` is `undefined`, it is equivalent to a vector of all `undefined` with the same length as the other vector. If both vectors are `undefined`, `@shuffle` returns a vector with all elements `undefined`. \\ - \\`E` must be an [integer](https://ziglang.org/documentation/master/#Integers), [float](https://ziglang.org/documentation/master/#Floats), [pointer](https://ziglang.org/documentation/master/#Pointers), or `bool`. The mask may be any vector length, and its length determines the result length.

    {#code_begin|test|vector_shuffle#} const std = @import("std"); const expect = std.testing.expect; test "vector @shuffle" { const a = @Vector(7, u8){ 'o', 'l', 'h', 'e', 'r', 'z', 'w' }; const b = @Vector(4, u8){ 'w', 'd', '!', 'x' }; // To shuffle within a single vector, pass undefined as the second argument. // Notice that we can re-order, duplicate, or omit elements of the input vector const mask1 = @Vector(5, i32){ 2, 3, 1, 1, 0 }; const res1: @Vector(5, u8) = @shuffle(u8, a, undefined, mask1); try expect(std.mem.eql(u8, &@as([5]u8, res1), "hello")); // Combining two vectors const mask2 = @Vector(6, i32){ -1, 0, 4, 1, -2, -3 }; const res2: @Vector(6, u8) = @shuffle(u8, a, b, mask2); try expect(std.mem.eql(u8, &@as([6]u8, res2), "world!")); }` + \\`E` must be an [integer](https://ziglang.org/documentation/master/#Integers), [float](https://ziglang.org/documentation/master/#Floats), [pointer](https://ziglang.org/documentation/master/#Pointers), or `bool`. The mask may be any vector length, and its length determines the result length. + \\ + \\```zig + \\const std = @import("std"); + \\const expect = std.testing.expect; + \\test "vector @shuffle" { + \\ const a = @Vector(7, u8){ 'o', 'l', 'h', 'e', 'r', 'z', 'w' }; + \\ const b = @Vector(4, u8){ 'w', 'd', '!', 'x' }; + \\ // To shuffle within a single vector, pass undefined as the second argument. + \\ // Notice that we can re-order, duplicate, or omit elements of the input vector + \\ const mask1 = @Vector(5, i32){ 2, 3, 1, 1, 0 }; + \\ const res1: @Vector(5, u8) = @shuffle(u8, a, undefined, mask1); + \\ try expect(std.mem.eql(u8, &@as([5]u8, res1), "hello")); + \\ // Combining two vectors + \\ const mask2 = @Vector(6, i32){ -1, 0, 4, 1, -2, -3 }; + \\ const res2: @Vector(6, u8) = @shuffle(u8, a, b, mask2); + \\ try expect(std.mem.eql(u8, &@as([6]u8, res2), "world!")); + \\} + \\``` , .arguments = &.{ "comptime E: type", @@ -1392,8 +1529,18 @@ pub const builtins = [_]Builtin{ .signature = "@splat(comptime len: u32, scalar: anytype) @Vector(len, @TypeOf(scalar))", .snippet = "@splat(${1:comptime len: u32}, ${2:scalar: anytype})", .documentation = - \\Produces a vector of length `len` where each element is the value `scalar`:

    {#code_begin|test|vector_splat#} const std = @import("std"); const expect = std.testing.expect; test "vector @splat" { const scalar: u32 = 5; const result = @splat(4, scalar); comptime try expect(@TypeOf(result) == @Vector(4, u32)); try expect(std.mem.eql(u32, &@as([4]u32, result), &[_]u32{ 5, 5, 5, 5 })); }` + \\Produces a vector of length `len` where each element is the value `scalar`: \\ + \\```zig + \\const std = @import("std"); + \\const expect = std.testing.expect; + \\test "vector @splat" { + \\ const scalar: u32 = 5; + \\ const result = @splat(4, scalar); + \\ comptime try expect(@TypeOf(result) == @Vector(4, u32)); + \\ try expect(std.mem.eql(u32, &@as([4]u32, result), &[_]u32{ 5, 5, 5, 5 })); + \\} + \\``` \\`scalar` must be an [integer](https://ziglang.org/documentation/master/#Integers), [bool](https://ziglang.org/documentation/master/#Primitive-Types), [float](https://ziglang.org/documentation/master/#Floats), or [pointer](https://ziglang.org/documentation/master/#Pointers). , .arguments = &.{ @@ -1406,14 +1553,29 @@ pub const builtins = [_]Builtin{ .signature = "@reduce(comptime op: std.builtin.ReduceOp, value: anytype) E", .snippet = "@reduce(${1:comptime op: std.builtin.ReduceOp}, ${2:value: anytype})", .documentation = - \\Transforms a [vector](https://ziglang.org/documentation/master/#Vectors) into a scalar value (of type `E`) by performing a sequential horizontal reduction of its elements using the specified operator `op`. + \\Transforms a [vector](https://ziglang.org/documentation/master/#Vectors) into a scalar value (of type + \\`E`) by performing a sequential horizontal reduction of its elements using the specified operator `op`. \\ \\Not every operator is available for every vector element type: - \\ - Every operator is available for [integer](https://ziglang.org/documentation/master/#Integers) vectors. - \\ - `.And`, `.Or`, `.Xor` are additionally available for `bool` vectors, - \\ - `.Min`, `.Max`, `.Add`, `.Mul` are additionally available for [floating point](https://ziglang.org/documentation/master/#Floats) vectors, \\ - \\Note that `.Add` and `.Mul` reductions on integral types are wrapping; when applied on floating point types the operation associativity is preserved, unless the float mode is set to `Optimized`.

    {#code_begin|test|vector_reduce#} const std = @import("std"); const expect = std.testing.expect; test "vector @reduce" { const value = @Vector(4, i32){ 1, -1, 1, -1 }; const result = value > @splat(4, @as(i32, 0)); // result is { true, false, true, false }; comptime try expect(@TypeOf(result) == @Vector(4, bool)); const is_all_true = @reduce(.And, result); comptime try expect(@TypeOf(is_all_true) == bool); try expect(is_all_true == false); }` + \\ - Every operator is available for [integer](https://ziglang.org/documentation/master/#Integers) vectors. + \\ - `.And`, `.Or`, `.Xor` are additionally available for `bool` vectors, + \\ - `.Min`, `.Max`, `.Add`, `.Mul` are additionally available for [floating point](https://ziglang.org/documentation/master/#Floats) vectors, + \\Note that `.Add` and `.Mul` reductions on integral types are wrapping; when applied on floating point types the operation associativity is preserved, unless the float mode is set to `Optimized`. + \\ + \\```zig + \\const std = @import("std"); + \\const expect = std.testing.expect; + \\test "vector @reduce" { + \\ const value = @Vector(4, i32){ 1, -1, 1, -1 }; + \\ const result = value > @splat(4, @as(i32, 0)); + \\ // result is { true, false, true, false }; + \\ comptime try expect(@TypeOf(result) == @Vector(4, bool)); + \\ const is_all_true = @reduce(.And, result); + \\ comptime try expect(@TypeOf(is_all_true) == bool); + \\ try expect(is_all_true == false); + \\} + \\``` , .arguments = &.{ "comptime op: std.builtin.ReduceOp", @@ -1425,7 +1587,22 @@ pub const builtins = [_]Builtin{ .signature = "@src() std.builtin.SourceLocation", .snippet = "@src()", .documentation = - \\Returns a `SourceLocation` struct representing the function's name and location in the source code. This must be called in a function.

    {#code_begin|test|source_location#} const std = @import("std"); const expect = std.testing.expect; test "@src" { try doTheTest(); } fn doTheTest() !void { const src = @src(); try expect(src.line == 9); try expect(src.column == 17); try expect(std.mem.endsWith(u8, src.fn_name, "doTheTest")); try expect(std.mem.endsWith(u8, src.file, "source_location.zig")); }` + \\Returns a `SourceLocation` struct representing the function's name and location in the source code. This must be called in a function. + \\ + \\```zig + \\const std = @import("std"); + \\const expect = std.testing.expect; + \\test "@src" { + \\ try doTheTest(); + \\} + \\fn doTheTest() !void { + \\ const src = @src(); + \\ try expect(src.line == 9); + \\ try expect(src.column == 17); + \\ try expect(std.mem.endsWith(u8, src.fn_name, "doTheTest")); + \\ try expect(std.mem.endsWith(u8, src.file, "source_location.zig")); + \\} + \\``` , .arguments = &.{}, }, @@ -1436,7 +1613,8 @@ pub const builtins = [_]Builtin{ .documentation = \\Performs the square root of a floating point number. Uses a dedicated hardware instruction when available. \\ - \\Supports [Floats](https://ziglang.org/documentation/master/#Floats) and [Vectors](https://ziglang.org/documentation/master/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). + \\Supports [Floats](https://ziglang.org/documentation/master/#Floats) and [Vectors](https://ziglang.org/documentation/master/#Vectors) of floats, with the caveat that + \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). , .arguments = &.{ "value: anytype", @@ -1449,7 +1627,8 @@ pub const builtins = [_]Builtin{ .documentation = \\Sine trigonometric function on a floating point number. Uses a dedicated hardware instruction when available. \\ - \\Supports [Floats](https://ziglang.org/documentation/master/#Floats) and [Vectors](https://ziglang.org/documentation/master/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). + \\Supports [Floats](https://ziglang.org/documentation/master/#Floats) and [Vectors](https://ziglang.org/documentation/master/#Vectors) of floats, with the caveat that + \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). , .arguments = &.{ "value: anytype", @@ -1462,7 +1641,8 @@ pub const builtins = [_]Builtin{ .documentation = \\Cosine trigonometric function on a floating point number. Uses a dedicated hardware instruction when available. \\ - \\Supports [Floats](https://ziglang.org/documentation/master/#Floats) and [Vectors](https://ziglang.org/documentation/master/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). + \\Supports [Floats](https://ziglang.org/documentation/master/#Floats) and [Vectors](https://ziglang.org/documentation/master/#Vectors) of floats, with the caveat that + \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). , .arguments = &.{ "value: anytype", @@ -1475,7 +1655,8 @@ pub const builtins = [_]Builtin{ .documentation = \\Tangent trigonometric function on a floating point number. Uses a dedicated hardware instruction when available. \\ - \\Supports [Floats](https://ziglang.org/documentation/master/#Floats) and [Vectors](https://ziglang.org/documentation/master/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). + \\Supports [Floats](https://ziglang.org/documentation/master/#Floats) and [Vectors](https://ziglang.org/documentation/master/#Vectors) of floats, with the caveat that + \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). , .arguments = &.{ "value: anytype", @@ -1488,7 +1669,8 @@ pub const builtins = [_]Builtin{ .documentation = \\Base-e exponential function on a floating point number. Uses a dedicated hardware instruction when available. \\ - \\Supports [Floats](https://ziglang.org/documentation/master/#Floats) and [Vectors](https://ziglang.org/documentation/master/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). + \\Supports [Floats](https://ziglang.org/documentation/master/#Floats) and [Vectors](https://ziglang.org/documentation/master/#Vectors) of floats, with the caveat that + \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). , .arguments = &.{ "value: anytype", @@ -1501,7 +1683,8 @@ pub const builtins = [_]Builtin{ .documentation = \\Base-2 exponential function on a floating point number. Uses a dedicated hardware instruction when available. \\ - \\Supports [Floats](https://ziglang.org/documentation/master/#Floats) and [Vectors](https://ziglang.org/documentation/master/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). + \\Supports [Floats](https://ziglang.org/documentation/master/#Floats) and [Vectors](https://ziglang.org/documentation/master/#Vectors) of floats, with the caveat that + \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). , .arguments = &.{ "value: anytype", @@ -1514,7 +1697,8 @@ pub const builtins = [_]Builtin{ .documentation = \\Returns the natural logarithm of a floating point number. Uses a dedicated hardware instruction when available. \\ - \\Supports [Floats](https://ziglang.org/documentation/master/#Floats) and [Vectors](https://ziglang.org/documentation/master/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). + \\Supports [Floats](https://ziglang.org/documentation/master/#Floats) and [Vectors](https://ziglang.org/documentation/master/#Vectors) of floats, with the caveat that + \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). , .arguments = &.{ "value: anytype", @@ -1527,7 +1711,8 @@ pub const builtins = [_]Builtin{ .documentation = \\Returns the logarithm to the base 2 of a floating point number. Uses a dedicated hardware instruction when available. \\ - \\Supports [Floats](https://ziglang.org/documentation/master/#Floats) and [Vectors](https://ziglang.org/documentation/master/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). + \\Supports [Floats](https://ziglang.org/documentation/master/#Floats) and [Vectors](https://ziglang.org/documentation/master/#Vectors) of floats, with the caveat that + \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). , .arguments = &.{ "value: anytype", @@ -1540,7 +1725,8 @@ pub const builtins = [_]Builtin{ .documentation = \\Returns the logarithm to the base 10 of a floating point number. Uses a dedicated hardware instruction when available. \\ - \\Supports [Floats](https://ziglang.org/documentation/master/#Floats) and [Vectors](https://ziglang.org/documentation/master/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). + \\Supports [Floats](https://ziglang.org/documentation/master/#Floats) and [Vectors](https://ziglang.org/documentation/master/#Vectors) of floats, with the caveat that + \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). , .arguments = &.{ "value: anytype", @@ -1553,7 +1739,8 @@ pub const builtins = [_]Builtin{ .documentation = \\Returns the absolute value of a floating point number. Uses a dedicated hardware instruction when available. \\ - \\Supports [Floats](https://ziglang.org/documentation/master/#Floats) and [Vectors](https://ziglang.org/documentation/master/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). + \\Supports [Floats](https://ziglang.org/documentation/master/#Floats) and [Vectors](https://ziglang.org/documentation/master/#Vectors) of floats, with the caveat that + \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). , .arguments = &.{ "value: anytype", @@ -1566,7 +1753,8 @@ pub const builtins = [_]Builtin{ .documentation = \\Returns the largest integral value not greater than the given floating point number. Uses a dedicated hardware instruction when available. \\ - \\Supports [Floats](https://ziglang.org/documentation/master/#Floats) and [Vectors](https://ziglang.org/documentation/master/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). + \\Supports [Floats](https://ziglang.org/documentation/master/#Floats) and [Vectors](https://ziglang.org/documentation/master/#Vectors) of floats, with the caveat that + \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). , .arguments = &.{ "value: anytype", @@ -1579,7 +1767,8 @@ pub const builtins = [_]Builtin{ .documentation = \\Returns the smallest integral value not less than the given floating point number. Uses a dedicated hardware instruction when available. \\ - \\Supports [Floats](https://ziglang.org/documentation/master/#Floats) and [Vectors](https://ziglang.org/documentation/master/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). + \\Supports [Floats](https://ziglang.org/documentation/master/#Floats) and [Vectors](https://ziglang.org/documentation/master/#Vectors) of floats, with the caveat that + \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). , .arguments = &.{ "value: anytype", @@ -1592,7 +1781,8 @@ pub const builtins = [_]Builtin{ .documentation = \\Rounds the given floating point number to an integer, towards zero. Uses a dedicated hardware instruction when available. \\ - \\Supports [Floats](https://ziglang.org/documentation/master/#Floats) and [Vectors](https://ziglang.org/documentation/master/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). + \\Supports [Floats](https://ziglang.org/documentation/master/#Floats) and [Vectors](https://ziglang.org/documentation/master/#Vectors) of floats, with the caveat that + \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). , .arguments = &.{ "value: anytype", @@ -1605,7 +1795,8 @@ pub const builtins = [_]Builtin{ .documentation = \\Rounds the given floating point number to an integer, away from zero. Uses a dedicated hardware instruction when available. \\ - \\Supports [Floats](https://ziglang.org/documentation/master/#Floats) and [Vectors](https://ziglang.org/documentation/master/#Vectors) of floats, with the caveat that [some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). + \\Supports [Floats](https://ziglang.org/documentation/master/#Floats) and [Vectors](https://ziglang.org/documentation/master/#Vectors) of floats, with the caveat that + \\[some float operations are not yet implemented for all float types](https://github.com/ziglang/zig/issues/4026). , .arguments = &.{ "value: anytype", @@ -1641,8 +1832,26 @@ pub const builtins = [_]Builtin{ .signature = "@This() type", .snippet = "@This()", .documentation = - \\Returns the innermost struct, enum, or union that this function call is inside. This can be useful for an anonymous struct that needs to refer to itself:

    {#code_begin|test|this_innermost#} const std = @import("std"); const expect = std.testing.expect; test "@This()" { var items = [_]i32{ 1, 2, 3, 4 }; const list = List(i32){ .items = items[0..] }; try expect(list.length() == 4); } fn List(comptime T: type) type { return struct { const Self = @This(); items: []T, fn length(self: Self) usize { return self.items.len; } }; }` + \\Returns the innermost struct, enum, or union that this function call is inside. This can be useful for an anonymous struct that needs to refer to itself: \\ + \\```zig + \\const std = @import("std"); + \\const expect = std.testing.expect; + \\test "@This()" { + \\ var items = [_]i32{ 1, 2, 3, 4 }; + \\ const list = List(i32){ .items = items[0..] }; + \\ try expect(list.length() == 4); + \\} + \\fn List(comptime T: type) type { + \\ return struct { + \\ const Self = @This(); + \\ items: []T, + \\ fn length(self: Self) usize { + \\ return self.items.len; + \\ } + \\ }; + \\} + \\``` \\When `@This()` is used at file scope, it returns a reference to the struct that corresponds to the current file. , .arguments = &.{}, @@ -1661,14 +1870,12 @@ pub const builtins = [_]Builtin{ \\```zig \\const std = @import("std"); \\const expect = std.testing.expect; - \\ \\test "integer truncation" { \\ var a: u16 = 0xabcd; \\ var b: u8 = @truncate(u8, a); \\ try expect(b == 0xcd); \\} \\``` - \\ \\Use [@intCast](https://ziglang.org/documentation/master/#intCast) to convert numbers guaranteed to fit the destination type. , .arguments = &.{ @@ -1684,29 +1891,29 @@ pub const builtins = [_]Builtin{ \\This function is the inverse of [@typeInfo](https://ziglang.org/documentation/master/#typeInfo). It reifies type information into a `type`. \\ \\It is available for the following types: - \\ - `type` - \\ - `noreturn` - \\ - `void` - \\ - `bool` - \\ - [Integers](https://ziglang.org/documentation/master/#Integers) - The maximum bit count for an integer type is `65535`. - \\ - [Floats](https://ziglang.org/documentation/master/#Floats) - \\ - [Pointers](https://ziglang.org/documentation/master/#Pointers) - \\ - `comptime_int` - \\ - `comptime_float` - \\ - `@TypeOf(undefined)` - \\ - `@TypeOf(null)` - \\ - [Arrays](https://ziglang.org/documentation/master/#Arrays) - \\ - [Optionals](https://ziglang.org/documentation/master/#Optionals) - \\ - [Error Set Type](https://ziglang.org/documentation/master/#Error-Set-Type) - \\ - [Error Union Type](https://ziglang.org/documentation/master/#Error-Union-Type) - \\ - [Vectors](https://ziglang.org/documentation/master/#Vectors) - \\ - [opaque](https://ziglang.org/documentation/master/#opaque) - \\ - `anyframe` - \\ - [struct](https://ziglang.org/documentation/master/#struct) - \\ - [enum](https://ziglang.org/documentation/master/#enum) - \\ - [Enum Literals](https://ziglang.org/documentation/master/#Enum-Literals) - \\ - [union](https://ziglang.org/documentation/master/#union) \\ + \\ - `type` + \\ - `noreturn` + \\ - `void` + \\ - `bool` + \\ - [Integers](https://ziglang.org/documentation/master/#Integers) - The maximum bit count for an integer type is `65535`. + \\ - [Floats](https://ziglang.org/documentation/master/#Floats) + \\ - [Pointers](https://ziglang.org/documentation/master/#Pointers) + \\ - `comptime_int` + \\ - `comptime_float` + \\ - `@TypeOf(undefined)` + \\ - `@TypeOf(null)` + \\ - [Arrays](https://ziglang.org/documentation/master/#Arrays) + \\ - [Optionals](https://ziglang.org/documentation/master/#Optionals) + \\ - [Error Set Type](https://ziglang.org/documentation/master/#Error-Set-Type) + \\ - [Error Union Type](https://ziglang.org/documentation/master/#Error-Union-Type) + \\ - [Vectors](https://ziglang.org/documentation/master/#Vectors) + \\ - [opaque](https://ziglang.org/documentation/master/#opaque) + \\ - `anyframe` + \\ - [struct](https://ziglang.org/documentation/master/#struct) + \\ - [enum](https://ziglang.org/documentation/master/#enum) + \\ - [Enum Literals](https://ziglang.org/documentation/master/#Enum-Literals) + \\ - [union](https://ziglang.org/documentation/master/#union) \\`@Type` is not available for [Functions](https://ziglang.org/documentation/master/#Functions). , .arguments = &.{ @@ -1746,7 +1953,23 @@ pub const builtins = [_]Builtin{ .documentation = \\`@TypeOf` is a special builtin function that takes any (nonzero) number of expressions as parameters and returns the type of the result, using [Peer Type Resolution](https://ziglang.org/documentation/master/#Peer-Type-Resolution). \\ - \\The expressions are evaluated, however they are guaranteed to have no *runtime* side-effects:

    {#code_begin|test|no_runtime_side_effects#} const std = @import("std"); const expect = std.testing.expect; test "no runtime side effects" { var data: i32 = 0; const T = @TypeOf(foo(i32, &data)); comptime try expect(T == i32); try expect(data == 0); } fn foo(comptime T: type, ptr: *T) T { ptr.* += 1; return ptr.*; }` + \\The expressions are evaluated, however they are guaranteed to have no + \\**runtime** side-effects: + \\ + \\```zig + \\const std = @import("std"); + \\const expect = std.testing.expect; + \\test "no runtime side effects" { + \\ var data: i32 = 0; + \\ const T = @TypeOf(foo(i32, &data)); + \\ comptime try expect(T == i32); + \\ try expect(data == 0); + \\} + \\fn foo(comptime T: type, ptr: *T) T { + \\ ptr.* += 1; + \\ return ptr.*; + \\} + \\``` , .arguments = &.{ "...", @@ -1780,3 +2003,5 @@ pub const builtins = [_]Builtin{ }, }, }; + +// DO NOT EDIT