Skip to content

Instantly share code, notes, and snippets.

@andrewrk
Created November 21, 2018 00:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save andrewrk/715cb50818d73dfca99eea5fc1f99500 to your computer and use it in GitHub Desktop.
Save andrewrk/715cb50818d73dfca99eea5fc1f99500 to your computer and use it in GitHub Desktop.
wip proposal I didn't even want to put on the issue tracker
const S = struct {
a: usize,
b: usize,
};
fn foo() S {
var result: S return = undefined;
result.a = 1234;
result.b = 5678;
// returning the return var is specially detected
return result;
}
fn foo() S {
var result: S return = undefined;
result.a = 1234;
result.b = 5678;
// return statements allowed even with result var in scope
return S{.a = 1, .b = undefined};
}
fn foo() S {
var result: S return = undefined;
result.a = 1234;
result.b = 5678;
// error: return var already in scope
var another: S return = undefined;
}
// void is easy to understand, it's no-ops all the way down
fn foo() void {
var result: void return = {};
}
// When the return type is a simple scalar,
// return variables are the same as normal variables.
fn foo(b: bool) i32 {
if (b) {
var result: i32 return = undefined;
result = 123;
return result;
} else {
var result: i16 return = undefined;
result = -1; // this modifies a temporary i16 value
return result; // implicitly casts the i16 value to i32 value
}
}
fn foo() ?S {
// This works, even though the return type is optional
var result: S return = undefined;
result.method();
// This pointer is guaranteed to be the return value
const ptr = &result;
return result;
}
fn foo() ?S {
// You can also declare the same type as the return value.
var result: ?S return = undefined;
// Writes the values directly to the callee's result value
result = S{
.a = 1234,
.b = 5678,
};
// bar function writes directly to the callee's result value
result = struct{fn bar()?S {return undefined;}}.bar();
return result;
}
fn foo() ?S {
var result: ?S return = undefined;
// error: pointer to return type not available
// because the actual function looks like: foo(sret *S) i1
// the result pointer is actually a *S not a *?S
const ptr = &result;
}
// This works the same as a scalar integer.
// return variables are treated exactly
// the same as normal variables.
fn foo() ?*i32 {
var result: *i32 return = undefined;
return result;
}
// Zig does not guarantee the layout of ?i32.
// So there is no copy elision guarantee here.
fn foo() ?i32 {
var result: ?i32 return = 1234;
return result;
}
// Zig does not guarantee the layout of anyerror!i32.
// So there is no copy elision guarantee here.
fn foo() anyerror!i32 {
var result: i32 return = 1234;
return result;
}
// This works the same as ?S
fn foo() anyerror!S {
var result: S return = undefined;
result = S{
.a = 1234,
.b = 5678,
};
return result;
}
// This works the same as anyerror!i32
fn foo() anyerror!?*i32 {
var result: *i32 return = undefined;
return result;
}
fn foo() anyerror!?S {
// TODO how does this work?
}
fn foo() anyerror!?i32 {
// TODO how does this work?
}
fn foo() void {
const value = blk: {
var result: S break :blk = undefined;
break :blk result;
};
var value: S = undefined;
{
&value
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment