Created
November 21, 2018 00:43
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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