Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

std interface reform (#1829) #2533

Closed
wants to merge 25 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
fb74105
initial interface work
tgschultz May 15, 2019
2b96933
blocked on mysterious degredation of Random(T) to *const Random(T) at…
tgschultz May 15, 2019
cbe52c8
still blocked, done what I can around that for now.
tgschultz May 16, 2019
1c865fd
I believe all Random interface uses are now updated. #2501 still a pr…
tgschultz May 16, 2019
06ed2d0
initial Stream interface(s) work
tgschultz May 17, 2019
6c5d69c
lots of work on stream interfaces. blocked on error set inferrence is…
tgschultz May 18, 2019
0fd84b5
working through error set inferrence issues.
tgschultz May 18, 2019
384cdf2
horrible assertion failure in stage1 finally resolved. my fault.
tgschultz May 19, 2019
609a899
local integration test seems to be passing
tgschultz May 19, 2019
dc75817
invalid line removed
tgschultz May 20, 2019
b4b0905
initial work on Allocator
tgschultz May 20, 2019
793f31d
new allocator pattern mostly working. notable flaws: use of asyncReal…
tgschultz May 20, 2019
20da13e
std tests passing
tgschultz May 20, 2019
03d619c
All integration tests passing
tgschultz May 21, 2019
df0982d
fixed 0-bit types
tgschultz May 21, 2019
48d38f7
oops, CAllocator
tgschultz May 21, 2019
093a565
and again
tgschultz May 21, 2019
bdf57f0
formatting fixes to interface.zig
tgschultz May 21, 2019
95b1fcd
Merge branch 'master' into git_stdlib-interface_reform_3
tgschultz May 22, 2019
23f6846
fix problems discovered by Windows CI.
tgschultz May 22, 2019
dcd5535
Merge branch 'git_stdlib-interface_reform_3' of https://github.com/tg…
tgschultz May 22, 2019
630100d
minor changes to interface.zig
tgschultz May 22, 2019
16f7922
ok... can't use const on that. not sure why I thought I could.
tgschultz May 22, 2019
930f415
someday I will stop making stupid mistakes. today is not that day.
tgschultz May 22, 2019
a61347c
and again
tgschultz May 22, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,7 @@ set(ZIG_STD_FILES
"hash/siphash.zig"
"hash_map.zig"
"heap.zig"
"interface.zig"
"io.zig"
"io/seekable_stream.zig"
"io/c_out_stream.zig"
Expand Down
36 changes: 18 additions & 18 deletions doc/docgen.zig
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ pub fn main() !void {
var direct_allocator = std.heap.DirectAllocator.init();
defer direct_allocator.deinit();

var arena = std.heap.ArenaAllocator.init(&direct_allocator.allocator);
var arena = std.heap.ArenaAllocator.init(direct_allocator.allocator());
defer arena.deinit();

const allocator = &arena.allocator;
const allocator = arena.allocator();

var args_it = os.args();

Expand All @@ -41,20 +41,20 @@ pub fn main() !void {
var out_file = try os.File.openWrite(out_file_name);
defer out_file.close();

var file_in_stream = in_file.inStream();
var file_in_stream = in_file.streams().inStream();

const input_file_bytes = try file_in_stream.stream.readAllAlloc(allocator, max_doc_file_size);
const input_file_bytes = try file_in_stream.readAllAlloc(allocator, max_doc_file_size);

var file_out_stream = out_file.outStream();
var buffered_out_stream = io.BufferedOutStream(os.File.WriteError).init(&file_out_stream.stream);
var file_out_stream = out_file.streams().outStream();
var buffered_out_stream = io.BufferedOutStream(os.File.OutStreamImpl).init(file_out_stream);

var tokenizer = Tokenizer.init(in_file_name, input_file_bytes);
var toc = try genToc(allocator, &tokenizer);

try os.makePath(allocator, tmp_dir_name);
defer os.deleteTree(allocator, tmp_dir_name) catch {};

try genHtml(allocator, &tokenizer, &toc, &buffered_out_stream.stream, zig_exe);
try genHtml(allocator, &tokenizer, &toc, buffered_out_stream.outStream(), zig_exe);
try buffered_out_stream.flush();
}

Expand Down Expand Up @@ -316,7 +316,7 @@ const Action = enum {
Close,
};

fn genToc(allocator: *mem.Allocator, tokenizer: *Tokenizer) !Toc {
fn genToc(allocator: var, tokenizer: *Tokenizer) !Toc {
var urls = std.HashMap([]const u8, Token, mem.hash_slice_u8, mem.eql_slice_u8).init(allocator);
errdefer urls.deinit();

Expand All @@ -327,7 +327,7 @@ fn genToc(allocator: *mem.Allocator, tokenizer: *Tokenizer) !Toc {
defer toc_buf.deinit();

var toc_buf_adapter = io.BufferOutStream.init(&toc_buf);
var toc = &toc_buf_adapter.stream;
var toc = toc_buf_adapter.outStream();

var nodes = std.ArrayList(Node).init(allocator);
defer nodes.deinit();
Expand Down Expand Up @@ -569,12 +569,12 @@ fn genToc(allocator: *mem.Allocator, tokenizer: *Tokenizer) !Toc {
};
}

fn urlize(allocator: *mem.Allocator, input: []const u8) ![]u8 {
fn urlize(allocator: var, input: []const u8) ![]u8 {
var buf = try std.Buffer.initSize(allocator, 0);
defer buf.deinit();

var buf_adapter = io.BufferOutStream.init(&buf);
var out = &buf_adapter.stream;
var out = buf_adapter.outStream();
for (input) |c| {
switch (c) {
'a'...'z', 'A'...'Z', '_', '-', '0'...'9' => {
Expand All @@ -589,12 +589,12 @@ fn urlize(allocator: *mem.Allocator, input: []const u8) ![]u8 {
return buf.toOwnedSlice();
}

fn escapeHtml(allocator: *mem.Allocator, input: []const u8) ![]u8 {
fn escapeHtml(allocator: var, input: []const u8) ![]u8 {
var buf = try std.Buffer.initSize(allocator, 0);
defer buf.deinit();

var buf_adapter = io.BufferOutStream.init(&buf);
var out = &buf_adapter.stream;
var out = buf_adapter.outStream();
try writeEscaped(out, input);
return buf.toOwnedSlice();
}
Expand Down Expand Up @@ -635,12 +635,12 @@ test "term color" {
testing.expectEqualSlices(u8, "A<span class=\"t32\">green</span>B", result);
}

fn termColor(allocator: *mem.Allocator, input: []const u8) ![]u8 {
fn termColor(allocator: var, input: []const u8) ![]u8 {
var buf = try std.Buffer.initSize(allocator, 0);
defer buf.deinit();

var buf_adapter = io.BufferOutStream.init(&buf);
var out = &buf_adapter.stream;
var out = buf_adapter.outStream();
var number_start_index: usize = undefined;
var first_number: usize = undefined;
var second_number: usize = undefined;
Expand Down Expand Up @@ -947,7 +947,7 @@ fn tokenizeAndPrint(docgen_tokenizer: *Tokenizer, out: var, source_token: Token)
return tokenizeAndPrintRaw(docgen_tokenizer, out, source_token, raw_src);
}

fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var, zig_exe: []const u8) !void {
fn genHtml(allocator: var, tokenizer: *Tokenizer, toc: *Toc, out: var, zig_exe: []const u8) !void {
var code_progress_index: usize = 0;

var env_map = try os.getEnvMap(allocator);
Expand Down Expand Up @@ -1448,7 +1448,7 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var
}
}

fn exec(allocator: *mem.Allocator, env_map: *std.BufMap, args: []const []const u8) !os.ChildProcess.ExecResult {
fn exec(allocator: var, env_map: *std.BufMap, args: []const []const u8) !os.ChildProcess.ExecResult {
const result = try os.ChildProcess.exec(allocator, args, null, env_map, max_doc_file_size);
switch (result.term) {
os.ChildProcess.Term.Exited => |exit_code| {
Expand All @@ -1473,7 +1473,7 @@ fn exec(allocator: *mem.Allocator, env_map: *std.BufMap, args: []const []const u
return result;
}

fn getBuiltinCode(allocator: *mem.Allocator, env_map: *std.BufMap, zig_exe: []const u8) ![]const u8 {
fn getBuiltinCode(allocator: var, env_map: *std.BufMap, zig_exe: []const u8) ![]const u8 {
const result = try exec(allocator, env_map, []const []const u8{
zig_exe,
"builtin",
Expand Down
42 changes: 23 additions & 19 deletions doc/langref.html.in
Original file line number Diff line number Diff line change
Expand Up @@ -5840,11 +5840,11 @@ test "global assembly" {
which has these fields:
</p>
<ul>
<li>{#syntax#}allocFn: fn (self: *Allocator, byte_count: usize, alignment: u29) Error![]u8{#endsyntax#} - where {#syntax#}Error{#endsyntax#} can be any error set.</li>
<li>{#syntax#}freeFn: fn (self: *Allocator, old_mem: []u8) void{#endsyntax#}</li>
<li>{#syntax#}asyncReallocFn: fn (self: *AnyAllocator, old_mem: []u8, old_align: u29, new_byte_count: usize, new_align: u29) Error![]u8{#endsyntax#} - where {#syntax#}Error{#endsyntax#} can be any error set.</li>
<li>{#syntax#}asyncShrinkFn: fn (self: *AnyAllocator, old_mem: []u8, old_align: u29, new_byte_count: usize, new_align: u29) []u8{#endsyntax#}</li>
</ul>
<p>
You may notice that this corresponds to the {#syntax#}std.mem.Allocator{#endsyntax#} interface.
You may notice that this corresponds to the {#syntax#}std.mem.AnyAllocator{#endsyntax#} interface.
This makes it convenient to integrate with existing allocators. Note, however,
that the language feature does not depend on the standard library, and any struct which
has these fields is allowed.
Expand Down Expand Up @@ -5873,12 +5873,13 @@ const assert = std.debug.assert;
var x: i32 = 1;

test "create a coroutine and cancel it" {
const p = try async<std.debug.global_allocator> simpleAsyncFn();
var async_allocator = std.debug.global_allocator.toAny();
const p = try async<&async_allocator> simpleAsyncFn();
comptime assert(@typeOf(p) == promise->void);
cancel p;
assert(x == 2);
}
async<*std.mem.Allocator> fn simpleAsyncFn() void {
async<*std.mem.AnyAllocator> fn simpleAsyncFn() void {
x += 1;
}
{#code_end#}
Expand All @@ -5895,7 +5896,8 @@ const assert = std.debug.assert;

test "coroutine suspend, resume, cancel" {
seq('a');
const p = try async<std.debug.global_allocator> testAsyncSeq();
var async_allocator = std.debug.global_allocator.toAny();
const p = try async<&async_allocator> testAsyncSeq();
seq('c');
resume p;
seq('f');
Expand Down Expand Up @@ -5930,7 +5932,8 @@ const std = @import("std");
const assert = std.debug.assert;

test "coroutine suspend with block" {
const p = try async<std.debug.global_allocator> testSuspendBlock();
var async_allocator = std.debug.global_allocator.toAny();
const p = try async<&async_allocator> testSuspendBlock();
std.debug.assert(!result);
resume a_promise;
std.debug.assert(result);
Expand Down Expand Up @@ -5973,9 +5976,10 @@ const assert = std.debug.assert;

test "resume from suspend" {
var buf: [500]u8 = undefined;
var a = &std.heap.FixedBufferAllocator.init(buf[0..]).allocator;
var a = std.heap.FixedBufferAllocator.init(buf[0..]).allocator();
var async_allocator = a.toAny();
var my_result: i32 = 1;
const p = try async<a> testResumeFromSuspend(&my_result);
const p = try async<&async_allocator> testResumeFromSuspend(&my_result);
cancel p;
std.debug.assert(my_result == 2);
}
Expand Down Expand Up @@ -6025,7 +6029,8 @@ var final_result: i32 = 0;

test "coroutine await" {
seq('a');
const p = async<std.debug.global_allocator> amain() catch unreachable;
var async_allocator = std.debug.global_allocator.toAny();
const p = async<&async_allocator> amain() catch unreachable;
seq('f');
resume a_promise;
seq('i');
Expand Down Expand Up @@ -8385,23 +8390,22 @@ pub fn main() void {
C has a default allocator - <code>malloc</code>, <code>realloc</code>, and <code>free</code>.
When linking against libc, Zig exposes this allocator with {#syntax#}std.heap.c_allocator{#endsyntax#}.
However, by convention, there is no default allocator in Zig. Instead, functions which need to
allocate accept an {#syntax#}*Allocator{#endsyntax#} parameter. Likewise, data structures such as
{#syntax#}std.ArrayList{#endsyntax#} accept an {#syntax#}*Allocator{#endsyntax#} parameter in
allocate accept an allocator parameter. Likewise, data structures such as
{#syntax#}std.ArrayList{#endsyntax#} accept an allocator parameter in
their initialization functions:
</p>
{#code_begin|test|allocator#}
const std = @import("std");
const Allocator = std.mem.Allocator;
const assert = std.debug.assert;

test "using an allocator" {
var buffer: [100]u8 = undefined;
const allocator = &std.heap.FixedBufferAllocator.init(&buffer).allocator;
const allocator = std.heap.FixedBufferAllocator.init(&buffer).allocator();
const result = try concat(allocator, "foo", "bar");
assert(std.mem.eql(u8, "foobar", result));
}

fn concat(allocator: *Allocator, a: []const u8, b: []const u8) ![]u8 {
fn concat(allocator: var, a: []const u8, b: []const u8) ![]u8 {
const result = try allocator.alloc(u8, a.len + b.len);
std.mem.copy(u8, result, a);
std.mem.copy(u8, result[a.len..], b);
Expand Down Expand Up @@ -8429,7 +8433,7 @@ fn concat(allocator: *Allocator, a: []const u8, b: []const u8) ![]u8 {
</p>
<ol>
<li>
Are you making a library? In this case, best to accept an {#syntax#}*Allocator{#endsyntax#}
Are you making a library? In this case, best to accept an allocator
as a parameter and allow your library's users to decide what allocator to use.
</li>
<li>Are you linking libc? In this case, {#syntax#}std.heap.c_allocator{#endsyntax#} is likely
Expand All @@ -8452,10 +8456,10 @@ pub fn main() !void {
var direct_allocator = std.heap.DirectAllocator.init();
defer direct_allocator.deinit();

var arena = std.heap.ArenaAllocator.init(&direct_allocator.allocator);
var arena = std.heap.ArenaAllocator.init(direct_allocator.allocator());
defer arena.deinit();

const allocator = &arena.allocator;
const allocator = arena.allocator();

const ptr = try allocator.create(i32);
std.debug.warn("ptr={*}\n", ptr);
Expand Down Expand Up @@ -8613,7 +8617,7 @@ test "string literal to constant slice" {
<p>
For example, the function's documentation may say "caller owns the returned memory", in which case
the code that calls the function must have a plan for when to free that memory. Probably in this situation,
the function will accept an {#syntax#}*Allocator{#endsyntax#} parameter.
the function will accept an allocator parameter.
</p>
<p>
Sometimes the lifetime of a pointer may be more complicated. For example, when using
Expand Down
4 changes: 2 additions & 2 deletions example/guess_number/main.zig
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const os = std.os;

pub fn main() !void {
var stdout_file = try io.getStdOut();
const stdout = &stdout_file.outStream().stream;
const stdout = stdout_file.streams().outStream();

try stdout.print("Welcome to the Guess Number Game in Zig.\n");

Expand All @@ -18,7 +18,7 @@ pub fn main() !void {
const seed = std.mem.readIntNative(u64, &seed_bytes);
var prng = std.rand.DefaultPrng.init(seed);

const answer = prng.random.range(u8, 0, 100) + 1;
const answer = prng.random().range(u8, 0, 100) + 1;

while (true) {
try stdout.print("\nGuess a number between 1 and 100: ");
Expand Down
4 changes: 2 additions & 2 deletions libc/process_headers.zig
Original file line number Diff line number Diff line change
Expand Up @@ -708,8 +708,8 @@ const PathTable = std.AutoHashMap([]const u8, *TargetToHash);

pub fn main() !void {
var direct_allocator = std.heap.DirectAllocator.init();
var arena = std.heap.ArenaAllocator.init(&direct_allocator.allocator);
const allocator = &arena.allocator;
var arena = std.heap.ArenaAllocator.init(direct_allocator.allocator());
const allocator = arena.allocator();
const args = try std.os.argsAlloc(allocator);
var search_paths = std.ArrayList([]const u8).init(allocator);
var opt_out_dir: ?[]const u8 = null;
Expand Down
4 changes: 2 additions & 2 deletions src-self-hosted/arg.zig
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ fn argInAllowedSet(maybe_set: ?[]const []const u8, arg: []const u8) bool {
}

// Modifies the current argument index during iteration
fn readFlagArguments(allocator: *Allocator, args: []const []const u8, required: usize, allowed_set: ?[]const []const u8, index: *usize) !FlagArg {
fn readFlagArguments(allocator: var, args: []const []const u8, required: usize, allowed_set: ?[]const []const u8, index: *usize) !FlagArg {
switch (required) {
0 => return FlagArg{ .None = undefined }, // TODO: Required to force non-tag but value?
1 => {
Expand Down Expand Up @@ -80,7 +80,7 @@ pub const Args = struct {
flags: HashMapFlags,
positionals: ArrayList([]const u8),

pub fn parse(allocator: *Allocator, comptime spec: []const Flag, args: []const []const u8) !Args {
pub fn parse(allocator: var, comptime spec: []const Flag, args: []const []const u8) !Args {
var parsed = Args{
.flags = HashMapFlags.init(allocator),
.positionals = ArrayList([]const u8).init(allocator),
Expand Down
9 changes: 5 additions & 4 deletions src-self-hosted/codegen.zig
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const event = std.event;
const assert = std.debug.assert;
const DW = std.dwarf;
const maxInt = std.math.maxInt;
const AnyAllocator = std.mem.AnyAllocator;

pub async fn renderToLlvm(comp: *Compilation, fn_val: *Value.Fn, code: *ir.Code) !void {
fn_val.base.ref();
Expand Down Expand Up @@ -46,7 +47,7 @@ pub async fn renderToLlvm(comp: *Compilation, fn_val: *Value.Fn, code: *ir.Code)
// Don't use ZIG_VERSION_STRING here. LLVM misparses it when it includes
// the git revision.
const producer = try std.Buffer.allocPrint(
&code.arena.allocator,
code.arena.allocator(),
"zig {}.{}.{}",
u32(c.ZIG_VERSION_MAJOR),
u32(c.ZIG_VERSION_MINOR),
Expand Down Expand Up @@ -80,7 +81,7 @@ pub async fn renderToLlvm(comp: *Compilation, fn_val: *Value.Fn, code: *ir.Code)
.dibuilder = dibuilder,
.context = context,
.lock = event.Lock.init(comp.loop),
.arena = &code.arena.allocator,
.arena = code.arena.allocator().toAny(),
};

try renderToLlvmModule(&ofile, fn_val, code);
Expand Down Expand Up @@ -142,9 +143,9 @@ pub const ObjectFile = struct {
dibuilder: *llvm.DIBuilder,
context: *llvm.Context,
lock: event.Lock,
arena: *std.mem.Allocator,
arena: AnyAllocator,

fn gpa(self: *ObjectFile) *std.mem.Allocator {
fn gpa(self: *ObjectFile) AnyAllocator {
return self.comp.gpa();
}
};
Expand Down
Loading