Flaw in DIP1000? Returning a Result Struct in DIP1000
Meta
jared771 at gmail.com
Wed Mar 21 19:15:41 UTC 2018
On Wednesday, 21 March 2018 at 17:13:40 UTC, Jack Stouffer wrote:
> Consider this example simplified from this PR
> https://github.com/dlang/phobos/pull/6281
>
> ------
> struct GetoptResult
> {
> Option[] options;
> }
>
> struct Option
> {
> string optShort;
> string help;
> }
>
> GetoptResult getopt(T...)(scope T opts) @safe
> {
> GetoptResult res;
> auto o = Option(opts[0], opts[1]);
> res.options ~= o;
> return res;
> }
>
> void main() @safe
> {
> bool arg;
> getopt("arg", "info", &arg);
> }
> ------
>
> $ dmd -dip1000 -run main.d
>
> ------
> main.d(16): Error: scope variable o assigned to non-scope res
> main.d(23): Error: template instance `onlineapp.getopt!(string,
> string, bool*)` error instantiating
> ------
>
> The only way I've found to make the code compile and retain the
> pre-dip1000 behavior is to change the Option construction to
>
> ------
> auto o = Option(opts[0].idup, opts[1].idup);
> ------
>
> How can we return non-scoped result variables constructed from
> scope variables without copies?
I thought that maybe adding a function to Option and marking it
as `scope` would work:
struct GetoptResult
{
Option[] options;
void addOptions(scope Option opt) @safe scope
{
//Error: scope variable opt assigned to non-scope this
options ~= opt;
}
}
But the compiler doesn't like that. However, I _did_ get it
working by doing this:
GetoptResult getopt(T...)(scope T opts) @safe
{
return GetoptResult([Option(opts[0], opts[1])]);
}
Which is not ideal, obviously, but the notion that some code has
to be rewritten to accomodate ownership semantics is not a new
one; one of the major complaints I've seen about Rust is that it
requires you to adjust your coding style to satisfy the borrow
checker.
More information about the Digitalmars-d
mailing list